Необходимо в формате 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, но для пассажиров и время отлета, и время прилета всегда указываются в местном времени.
Комментариев нет:
Отправить комментарий