2008-10-08 3 views
12

Есть ли лучший способ сделать это?Есть ли лучший способ завтра найти полночь?

-(NSDate *)getMidnightTommorow { 
    NSCalendarDate *now = [NSCalendarDate date]; 
    NSCalendarDate *tomorrow = [now dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0]; 
    return [NSCalendarDate dateWithYear:[tomorrow yearOfCommonEra] 
            month:[tomorrow monthOfYear] 
            day:[tomorrow dayOfMonth] 
            hour:0 
           minute:0 
           second:0 
           timeZone:[tomorrow timeZone]]; 
} 

Обратите внимание, что я всегда хочу в полночь, даже если это случается в полночь, когда я делаю этот призыв, однако если это случается 23:59:59, я, конечно, хочу полночь, что приходит через одну секунду.

Функции естественного языка кажутся шелушащимися, и я не уверен, что сделал бы Cocoa, если я пройду 32 в поле «день». (Если бы я мог работать падение [теперь dateByAddingYears: ...] вызов)

ответ

25

От documentation:

Использование NSCalendarDate сильно обескуражен. Он еще не устарел, однако он может быть в следующем выпуске ОС после Mac OS X версии 10.5. Для календарных расчетов, вы должны использовать подходящие комбинации из NSCalendar, NSDate и NSDateComponents, как описаны в Календарях в Dates and Times Programming Topics for Cocoa.

После этого совет:

NSDate *today = [NSDate date]; 

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 

NSDateComponents *components = [[NSDateComponents alloc] init]; 
components.day = 1; 
NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0]; 
[components release]; 

NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 
components = [gregorian components:unitFlags fromDate:tomorrow]; 
components.hour = 0; 
components.minute = 0; 

NSDate *tomorrowMidnight = [gregorian dateFromComponents:components]; 

[gregorian release]; 
[components release]; 

(я не уверен, экспромтом, если это является наиболее эффективной реализации, но он должен служить в качестве указателя в правильном направлении.)

Примечание : Теоретически вы можете уменьшить количество кода здесь, разрешив объект компонентов даты со значениями, превышающими диапазон нормальных значений для компонента (например, просто добавив 1 к компоненту дня, что может привести к его значению 32) , Однако, хотя dateFromComponents:может терпеть значения вне пределов, это не гарантируется. Вам настоятельно рекомендуется не полагаться на него.

+0

И следуя из этого указатель, похоже, я могу вырезать большую часть этого, поскольку dateFromComponents * does *, похоже, терпит дни до конца месяца. – Dre 2008-10-08 18:07:31

+0

dateFromComponents * может * переносить значения вне пределов, но это не гарантируется. Вам настоятельно рекомендуется не полагаться на это. – mmalc 2008-10-08 20:25:08

+0

Я на восточном побережье, и весь день сегодня, когда я делаю вышеупомянутое преобразование, я получаю 1AM (у меня время -5 часов, но кажется, что NSCalendar убежден, что это -4 часа. (Даже если я явно установить часовой пояс) – 2011-02-23 21:54:20

0

Преобразуйте текущую дату и время в дату Unix (секунды с 1970 года) или стиль DOS (с 1980 года), затем добавьте 24 часа и преобразуйте их обратно. Затем сбросьте часы, минуты и секунды до нуля, чтобы добраться до полуночи.

+0

Не подходит для некоторых крайних случаев с летней экономией. – Andrew 2008-10-08 06:22:27

7

Нет, это будет так же, как вы используете, чтобы найти полночь сегодня.

4
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 

NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:(24 * 60 * 60)]; 

NSDateComponents *components = [gregorian components:(NSYearCalendarUnit | 
                 NSMonthCalendarUnit | 
                 NSDayCalendarUnit) 
              fromDate:tomorrow]; 

NSDate *midnight = [gregorian dateFromComponents:components]; 
0

Вы могли бы попробовать этот способ:

NSCalendar *calendar = [NSCalendar currentCalendar]; 
NSDateComponents *comps = [[NSDateComponents alloc] init]; 
[comps setDay:1]; 
NSDate *tomorrow = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0]; //it gives us tomorrow with current time 
NSDate *midnight = [calendar startOfDayForDate:tomorrow]; //here we get next midnight 

Это также легко получить интервал в секундах, если это необходимо, чтобы создать NSTimer:

double intervalToMidnight = midnight.timeIntervalSinceNow; 
Смежные вопросы