It is necessary to send / receive dates via API in json format. How to handle and store temporary zones?

I noticed that dates from NSString to NSDate with time zones are automatically converted to 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]); 

Log:

 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 

This means that in order to correctly process the date, you need to define a time zone on the line and store the NSTimeZone time zone next to the NSDate date?

 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]); 

Log:

 date is: 08.11.2016 07:00:00 
  • one
    NSDate is always in UTC (there is only one time in the world). To display, transfer to the desired timeZone. - Andrew Romanov
  • one
    From the documentation: NSDate contains a point in time, regardless of calendars or time zones. - Andrew Romanov
  • I advise you to send in timestamp-format, if there is no goal for a timezone - markov
  • Timezone is definitely needed. It seems the only solution is to send 2 fields timestamp + timeZoneOffset - Aleksey Alybin
  • Well, this is probably not the only thing, but the right one. In general, here is how - NSDate completely untied from the timezone, it means the moment of time, not the date / time. That is, when parsing, the poem will have to be dumped into two fields - the timezone and timestamp. You can send it in a specific timezone with its indication in the string. To do this, set the timeZone formatter and use stringFromDate: The normal NSDate goes to the entrance, well, just prepare it so that it shows the right time in the right time zone. And the server again takes your line and subtracts the timezone and timestamp separately from it - markov

2 answers 2

I use three rules:

  1. NSDate internal representation is always UTC.
  2. When interacting with the server, you should use UTC and not bother with ritual dances.
  3. When displaying or parsing the time entered on the client side, use NSDateFormatter with the current locale. IOS / Mac OS will figure out what time is currently installed on a specific client. You can add / use any format, but it is assumed that the user always uses the current local time.

The closest analogy is the table of flights. Airplanes themselves fly at UTC, but for passengers both the departure time and arrival time are always indicated in local time.

    When storing data on the server, use the numeric date view, measured in seconds from 1970, when processing the data in the client, use NSDate