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]];