Страницы

Поиск по вопросам

вторник, 9 июля 2019 г.

Какой формат дат лучше подходит для API?

Необходимо в формате json отправлять/получать даты по API. Как обрабатывать и хранить временные зоны?
Заметил, что даты из NSString в NSDateс временными зонами автоматически конвертируются в UTC.
// date with time zone NSString *dateString = @"2016-11-08T07:00:00.000+11:00"; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ";
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"CDT"]; NSLog(@"1. CDT date = %@", [dateFormatter dateFromString:dateString]);
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; NSLog(@"2. UTC date = %@", [dateFormatter dateFromString:dateString]);
dateFormatter.timeZone = [NSTimeZone systemTimeZone]; NSLog(@"3. system date = %@", [dateFormatter dateFromString:dateString]);
// date without time zone dateString = @"2016-11-08"; dateFormatter.dateFormat = @"yyyy-MM-dd";
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"CDT"]; NSLog(@"4. CDT date = %@", [dateFormatter dateFromString:dateString]);
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; NSLog(@"5. UTC date = %@", [dateFormatter dateFromString:dateString]);
dateFormatter.timeZone = [NSTimeZone systemTimeZone]; NSLog(@"6. system date = %@", [dateFormatter dateFromString:dateString]);
Лог:
1. CDT date = 2016-11-07 20:00:00 +0000 2. UTC date = 2016-11-07 20:00:00 +0000 3. system date = 2016-11-07 20:00:00 +0000 4. CDT date = 2016-11-08 06:00:00 +0000 5. UTC date = 2016-11-08 00:00:00 +0000 6. system date = 2016-11-07 21:00:00 +0000
Это значит, что для корректной обработки даты надо по строке определять временную зону и рядом с датой NSDate хранить временную зону NSTimeZone?
NSString *dateString = @"2016-11-08T07:00:00.000+03:00"; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ";
NSDateFormatter *dateFormatterForPrint = [[NSDateFormatter alloc] init]; dateFormatterForPrint.timeZone = [self timeZoneFromDateString:dateString]; dateFormatterForPrint.dateFormat = @"dd.MM.yyyy HH:mm:ss";
NSDate *date = [dateFormatter dateFromString:dateString]; NSLog(@"date is: %@", [dateFormatterForPrint stringFromDate:date]);
Лог:
date is: 08.11.2016 07:00:00


Ответ

Я пользуюсь тремя правилами:
внутреннее представление NSDate - всегда UTC. При взаимодействии с сервером надо использовать UTC и не заморачиваться с ритуальными танцами При отображении или парсинге времени, введенного на стороне клиента надо испльзовать NSDateFormatter с текущей локалью. IOS/Mac OS разберется, какое в данный момент время установлено на конкретном клиенте. Можно завдвать/использовать любой формат, но предполагается, что юзер всегда использует текущее местное время.
Ближайшая аналогия - таблица авиарейсов. Сами самолеты летают по UTC, но для пассажиров и время отлета, и время прилета всегда указываются в местном времени.

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

Отправить комментарий