Анализ даты / времени в iOS: как работать (или не работать) с часовыми поясами?

#objective-c #ios #nsdate #nsdateformatter

#objective-c #iOS #nsdate #nsdateformatter

Вопрос:

У меня есть ASP.NET Веб-сайт MVC 3, который взаимодействует с моим приложением для iOS через JSON. Как часть объектов, отправляемых в ответе JSON, у меня есть даты в формате, yyyy-MM-dd HH:mm:ss ZZZ который выводит 2011-04-05 16:28:22 -07:00 . Как мне проанализировать это в iOS?

Это код, с которым я сейчас возюсь:

 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSDate *date = [dateFormatter dateFromString:@"2011-04-05T16:28:22-0700"];

NSLog(@"%@; %@; %@", dateFormatter, date, [NSTimeZone localTimeZone]);
  

Первое, на что следует обратить внимание, это то, что 2011-04-05 16:28:22 -07:00 должно выглядеть так 2011-04-05T16:28:22-0700 , где a T заменяет первый пробел (предполагая, что это означает время или с чего начинается временная часть строки?), второй пробел удаляется и двоеточие в часовом поясе удаляется. Я полагаю, что найду способ отформатировать строку, которая .NET отправляет обратно, чтобы соответствовать строке, которую будет анализировать iOS.

Реальная проблема заключается в том, что выводимая дата на 7 часов опережает ту, которую я отправил в ответе JSON. Итак, iOS выводит 2011-04-05 16:28:22 -07:00 как 2011-04-05 23:28:22 0000 , и это неправильно, насколько это касается моего приложения.

Единственное решение, которое я нашел на данный момент, — отправить дату в формате JSON как 2011-04-05 16:28:22 00:00 , но это опять неправильно, потому что я изменяю, какой должна быть реальная дата.

В любом случае, я был бы признателен, если бы кто-нибудь взглянул и дал мне знать, как я могу проанализировать строку даты .NET выводит через формат yyyy-MM-dd HH:mm:ss ZZZ (который, я полагаю, можно переписать yyyy-MM-ddTHH:mm:ssZZZ ) в NSDate объект, который я могу использовать в iOS.

Комментарии:

1. Когда вы говорите о выводе iOS, вы имеете в виду NSLog? Если это так, NSLog всегда по умолчанию выводит GMT. Итак, с вашим кодом все в порядке.

2. Да, это то, что я имел в виду. Но если NSLog выводится в GMT, что говорит UILabel вывод?

3. NSDate сохраняет время как GMT. Вам придется использовать метод NSDateFormatter -stringFromDate при отображении любой даты в виде строки. NSDateFormatter также использует текущий часовой пояс по умолчанию.

4. Также рассмотрите возможность настройки, locale как предложено в технических вопросах и ответах Apple 1480 .

Ответ №1:

Я не знаю, насколько это правильно, но в конечном итоге я обнаружил, что в .NET я должен сделать DateTime.ToUniversalTime().ToString("yyyy-MM-ddHH:mm:ss") и на стороне iOS я должен сделать это:

 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[dateFormatter setDateFormat:@"yyyy-MM-ddHH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:@"2011-04-0600:28:27"];
  

Только тогда при NSLog выводе дата будет правильной, поэтому я предполагаю, что я наконец получил правильную дату / время.

Ответ №2:

Ваш код для анализа даты в iOS верен: 2011-04-05 16:28:22 -07:00 и 2011-04-05 23:28:22 0000 представляют одно и то же время, просто в разных часовых поясах. Ваша единственная проблема заключается в том, что NSDate фактически не хранит часовой пояс и поэтому [date description] выводит данные с использованием UTC.

Ответ №3:

Вам почти наверняка лучше просто использовать время UTC везде для обмена и не беспокоиться о часовых поясах. Я уверен, что вы сможете понять, что ваш ASP.NET код для этого, и его также легче анализировать на принимающей стороне. NSDateFormatter использует стандартный синтаксис форматирования даты в Юникоде, о котором вы можете прочитать здесь.

Комментарии:

1. Я вижу, я изменил . СЕТЕВАЯ сторона для вывода по универсальному времени, но я не уверен, как анализировать строку на стороне iOS. Вот ответ JSON: {"Start":"/Date(1302048496487)/","End":"/Date(1302055696487)/"} . Каким был бы правильный код для анализа этого?

2. К сожалению, игнорирование часовых поясов, хотя и удобно для компьютера, не «полностью корректно» для человека. Переход на летнее время и т.д. делают это еще более трудоемким: (

3. Я не имел в виду в целом, я имел в виду на сервере. Поверьте мне, я пишу приложение для сигнализации и потратил слишком много времени, разбираясь с часовыми поясами и настройками форм. 🙂

4. @NicholasRiley Просто держит вас в напряжении 😉 (В настоящее время я участвую в битве за часовые пояса, в которой, я не думаю, что выиграю …)