Почему мой часовой пояс не сохраняется в моем NSDate?
Я должен инициализировать объект NSDate из NSString в objective-c. Я делаю это так:
NSString *dateString = [[webSentence child:@"DateTime"].text stringByReplacingOccurrencesOfString:@"T" withString:@" "];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-mm-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Budapest"]];
NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:dateString];
Например: когда я пытаюсь использовать его со строковым значением @ "2011-01-02 17:49:54" Я получаю NSDate 2011-01-02 16:49:54 +0000. Как вы видите, разница между двумя значениями составляет один час. NSDate имеет неправильное значение, оно должно быть точно таким же, как я определил в моей строке в часовом поясе, установленном в dateFormatter. Кажется, он использует мою дату, определенную как строка в формате UTC, даже если я установил часовой пояс для "Европа/Будапешт". Как я могу исправить эту проблему?
Спасибо!
Ответы
Ответ 1
Две вещи:
1) у вас есть ошибка в вашей строке формата даты. Вы должны использовать MM
месяц, а не MM
(нижний регистр мм в минутах)
2) после создания объекта NSDate вам необходимо использовать метод NSDateFormatter stringFromDate:
, чтобы создать строку даты, локализованную в определенный часовой пояс. Если вы просто сделаете прямой NSLog() на объекте NSDate, он покажет дату как GMT по умолчанию (GMT на один час после Будапештского времени).
Ответ 2
NSDate хранит даты относительно стандартной контрольной даты. Из документов класса:
"Единственный примитивный метод NSDate, timeIntervalSinceReferenceDate, обеспечивает основу для всех других методов в интерфейсе NSDate. Этот метод возвращает значение времени относительно абсолютной контрольной даты - первого момента 1 января 2001 года, GMT".
NSDate сам по себе не имеет понятия о часовых поясах. Итак, NSDateFormatter поступил правильно: он конвертировал дату, в которой вы сказали, что имеет смещение по GMT (путем указания часового пояса) и дал вам "нормализованный" NSDate для этой даты.
Если вы хотите увидеть дату, представленную в часовом поясе Европа/Будапешт, используйте либо существующий формат даты (-stringFromDate:), либо соответствующий метод описания NSDate (например, -descriptionWithCalendarFormat: timeZone: locale:).
P.S.- Вам вообще не нужно выделять /init в своем коде, как написано. В не-ARC, который будет утечкой.
P.P.S.- Ваш формат даты неверен и дает бессмысленные результаты. Я пошел дальше и очистил ваш код следующим образом (проверено в ARC):
NSString *dateString = @"2011-09-02 17:49:54";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *tz = [NSTimeZone timeZoneWithName:@"Europe/Budapest"];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:tz];
NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(@"%@", [dateFormatter stringFromDate:date]);
NSLog(@"%@", [date descriptionWithCalendarFormat:nil timeZone:tz locale:nil]);