NSDate установка времени, а не ожидаемый результат

У меня есть следующий код для установки времени на дату равным 0 часам, 0 минутам, 0 секундам, используя компоненты YEAR, MONTH и DAY от даты для создания нового:

NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit) fromDate:date];
NSDate *newDate = [gregorian dateFromComponents:comps];
NSLog(@"date: %@, newDate: %@", date, newDate);

Выход:

date: 2012-11-06 11:44:09 +0000, newDate: 2012-11-05 23:00:00 +0000

но я ожидал, что новая дата будет: 2012-11-06 00:00:00 +0000Что происходит, что я должен знать?

2 ответа

Решение

NSLog показывает даты, используя -[NSDate description] который, в свою очередь, преобразует абсолютное время, хранящееся в NSDate в строку. Это преобразование выполняется с использованием UTC в качестве часового пояса.

В вашем случае, вероятно, лучше всего также выполнить вычисления даты в UTC. Для этого настройте объект календаря, который выполняет вычисления:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];

См. Этот ответ для аналогичного вопроса переполнения стека.

Это должно решить вашу проблему с переходом на летнее время:

NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];

[formatter setCalendar:[NSCalendar currentCalendar]];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];

NSString *string = [formatter stringFromDate:[NSDate date]];
Другие вопросы по тегам