2010-12-01 5 views
8

나는 데이터를 저장하기 위해 코어 데이터를 사용하는 응용 프로그램을 작성 중입니다. 여기에는 시간이 아닌 데이트에만 관심이있는 데이트 필드가 포함됩니다.시간 요소가없는 날짜를 만드는 NSDate 모범 사례

+ (NSDate *)dateWithNoTime:(NSDate *)dateTime { 
if(dateTime == nil) { 
    dateTime = [NSDate date]; 
} 
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateTime]; 
NSDate *dateOnly = [[NSCalendar currentCalendar] dateFromComponents:comps]; 
[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)];   // Push to Middle of day. 
return dateOnly; 

}

난 후, 다음과 같이 설정된 시간에, 정규화 된 날짜를 반환하는 I 날짜 (안 시간)을 기준으로 기록을 선택해야하고 그래서있는 NSDate에 카테고리를 만들었습니다 핵심 데이터 저장소에 데이터를 추가 할 때이 메서드를 사용합니다 (기본 데이터 값을 설정하는 데이 메서드를 사용하는 설정자가 있음). 그리고이 메서드를 사용하여 가져 오기 요청을 수행 할 때 날짜를 비교하는 데 사용하는 날짜를 만듭니다. . 이론적으로 이것은 항상 작동해야합니다 - 즉 내가 찾고있는 날짜를 고르는 것.

시간대 나 로케일을 변경하면 어떤 영향을 미치는지 완전히 확신 할 수 없으므로 약간 긴장됩니다. 여전히 작동할까요?

시간에 관심이없는 경우에만 날짜를 저장하고 검색 할 때 모범 사례로 간주되는 것은 무엇입니까?

건배.

토론을 읽은 후 편집

내가 다음과 같이 일하려면 코드를 수정해야한다고 생각 좋습니다. 특정 달력 시스템과 특정 표준 시간대 (UTC)로 푸시해야한다면 날짜를 설정할 때와 읽은 날짜에 관계없이 날짜가 항상 동일해야합니다. 이 새로운 코드에 대한 의견은 높이 평가되었습니다.

+ (NSDate *)dateWithNoTime:(NSDate *)dateTime { 
if(dateTime == nil) { 
    dateTime = [NSDate date]; 
} 

NSCalendar  *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; 
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease]; 
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit 
         fromDate:dateTime]; 

NSDate *dateOnly = [calendar dateFromComponents:components]; 

[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)];   // Push to Middle of day. 
return dateOnly; 

}

+0

솔루션을 제공해 주셔서 감사합니다. : D 조금만 보정 : 라인 : '[dateOnly dateByAddingTimeInterval (60.0 * 60.0 * 12.0)]' 가되어야한다 'dateOnly = dateOnly dateByAddingTimeInterval (60.0 * 60.0 * 12.0)]; ' –

답변

5

여기서 다루는 몇 가지 문제가있다. 첫째, 언급 한대로 시간대. "일 정"개념을 변경하는 일광 절약에 대해 걱정할 필요가 있습니다.

Apple 엔지니어가 몇 가지 유용한 정보를 제공하고 몇 가지 모범 사례에 대해 설명하는 CocoaDev의 this discussion을 살펴보십시오.

+0

고마워. 토론을 읽은 후에는 항상 같은 달력 시스템과 시간대를 사용하여 저장하고 비교해야합니다. 나는이 새로운 사고에 기초하여 나의 질문에 새로운 코드를 추가했다. – SimonB

3

더 간단한 솔루션은 특정 범위 내의 날짜를 찾는 술어를 사용하는 것입니다.

NSCalendarComponent를 사용하여 "day"의 시작 날짜와 종료 날짜를 만든 다음이를 술어에 포함시킵니다.

NSPredicate *p=[NSPredicate predicateWithFormat:@"[email protected] <= date <= [email protected]",startDate,endDate]; 

이렇게하면 복잡성을 크게 줄일 수 있습니다. 날짜 및 시간 프로그래밍은 믿을 수 없을 정도로 복잡합니다. 어떤 일을 할 준비를하십시오.

2

나는 또한 시간을 고려하지 않고 날짜를 비교하기 위해 NSDate을 가질 필요가있는 시나리오에서 종료되었습니다.

필터 메커니즘을 사용하고 UI의 일부로 사용자가 오늘 시작일과 종료일로 최소 날짜를 선택한 경우 형식의 문자열과 달리 "모든 기간"이 표시됩니다 :

2006년 1월 5일 - 24/12/2009

그래서 나는 NSDate+date를 사용하여 오늘날의 일을하고, 종료 날짜와 비교 할 필요가 있었다. 종료일은 UIDatePicker에서 설정되었지만 +date은 현재 날짜와 시간을 반환했습니다.

그래서이 짧은 방법을 사용하여 날짜 객체를 받고 NSDateComponentsNSCalendar 클래스를 사용하여 일, 월 및 연도를 추출합니다.

이들 3 개 파라미터는 다음 새 NSDate 사용 NSDateFormatter's 생성하기 위해 사용된다 - dateFromString: 방법, 결과는 파라미터 date로하지만 시간없이 (전통적인 인간 개념) 같은 "날짜"에 대응하는 NSDate이다.

- (NSDate *)strictDateFromDate:(NSDate *)date{ 
    NSUInteger flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 
    NSDateComponents *components = [[NSCalendar currentCalendar] components:flags 
                    fromDate:[NSDate date]]; 
    NSString *stringDate = [NSString stringWithFormat:@"%d/%d/%d", components.day, components.month, components.year]; 

    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; 
    formatter.dateFormat = @"dd/MM/yyyy"; 

    return [formatter dateFromString:stringDate]; 
} 

앞으로도이 기능을 사용하고 즐기십시오.

+0

이 값을 시도했지만 반환 값에 타임 스탬프가 포함되어 있습니다 !!! –