Почему мой часовой пояс не сохраняется в NSDate? - PullRequest
15 голосов
/ 15 января 2012

Я должен инициализировать объект NSDate из NSString в target-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];

Eg: когда я пробую это со строковым значением @ "2011-01-02 17:49:54" я получаю NSDate 2011-01-02 16:49:54 +0000. Как вы можете видеть, разница между двумя значениями составляет один час. NSDate имеет неправильное значение, оно должно быть точно таким же, как я определил в своей строке в часовом поясе, который я установил в dateFormatter. Кажется, он использует мою дату, определенную в строке как UTC, даже если я установил часовой пояс "Европа / Будапешт". Как я могу решить эту проблему?

Спасибо!

Ответы [ 2 ]

27 голосов
/ 15 января 2012

NSDate хранит даты относительно стандартной контрольной даты.Из класса документов:

"Единственный примитивный метод NSDate, timeIntervalSinceReferenceDate, обеспечивает основу для всех других методов в интерфейсе NSDate. Этот метод возвращает значение времени относительно абсолютной ссылочной даты - первого моментаот 1 января 2001 года по Гринвичу. "

NSDate сама по себе не имеет понятия часовых поясов.Таким образом, NSDateFormatter сделал правильную вещь: он преобразовал дату, о которой вы сказали, что она имеет смещение по Гринвичу (указав часовой пояс), и дал вам «нормализованную» NSDate для этой даты.

Если вы хотитесм. дату, представленную в часовом поясе Европы / Будапешта, либо используйте существующий форматер даты (-stringFromDate :), либо соответствующий метод описания NSDate (например, -descriptionWithCalendarFormat: timeZone: locale:).

PS - Вы неВам вообще не нужен alloc / init в вашем коде, как написано.В не ARC это будет утечка.

PPS - Ваш формат даты неверен и дает бессмысленные результаты.Я пошел дальше и очистил ваш код следующим образом (проверено в 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]);
14 голосов
/ 15 января 2012

Две вещи:

1) у вас есть ошибка в вашей строке формата даты. Вы должны использовать MM для месяца, а не mm (нижний регистр мм для минут)

2) после создания объекта NSDate вам нужно будет использовать метод NSDateFormatter stringFromDate:, чтобы сгенерировать строку даты, локализованную в определенном часовом поясе. Если вы просто выполните NSLog () для объекта NSDate, он по умолчанию будет показывать дату по Гринвичу (время по Гринвичу на один час меньше времени Будапешта)

...