Есть ли лучший способ найти полночь завтра? - PullRequest
12 голосов
/ 08 октября 2008

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

-(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, я, конечно, хочу, чтобы полночь наступила через одну секунду.

Функции на естественном языке кажутся нестабильными, и я не уверен, что сделал бы Какао, если бы я пропустил 32 в поле "день". (Если бы это сработало, я мог бы отбросить вызов [now dateByAddingYears: ...])

Ответы [ 6 ]

25 голосов
/ 08 октября 2008

Из документации :

Использование NSCalendarDate сильно не рекомендуется. Это еще не устарело, Однако это может быть в следующей основной ОС Выпуск после Mac OS X v10.5. За Календарные расчеты, вы должны используйте подходящие комбинации NSCalendar, NSDate и NSDateComponents, как описано в Календари в Даты и время Темы программирования для какао .

Следуя этому совету:

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: может переносить значения за пределами допустимого, это не гарантируется. Вам настоятельно рекомендуется не полагаться на это.

7 голосов
/ 08 октября 2008

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

4 голосов
/ 06 августа 2009
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];
1 голос
/ 14 мая 2009
[NSDate dateWithNaturalLanguageString:@"midnight tomorrow"];
0 голосов
/ 21 февраля 2016

Вы можете попробовать это так:

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;
0 голосов
/ 08 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...