Format NSDate for local time and UTC

I have the need to store both local time as per users timezone and UTC time in a transaction table using core data


What I want is as follows


createDate = "2016-12-26T03:19:38+08:00"; <--- This should reflect the users local timezone, in this case I am in China so GMT+8 is correct

createDateUtc = "2016-12-25T19:19:38+00:00"; <---- This should reflect the same timestamp but represented in UTC


I have tried various formatters but for some reason I cannot get the result I want


Here are my two formatters


NSDateFormatter *dateFormatterWithTz = [[NSDateFormatter alloc] init];
[dateFormatterWithTz setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];

NSDateFormatter *dateFormatterUtc = [[NSDateFormatter alloc] init];
[dateFormatterUtc setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
//[dateFormatterUtc setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];



here is how I create the date variables


  NSDate *createdDateUtc = [NSDate date]; 
  NSDate *createdDate = [NSDate dateWithTimeInterval:[[NSTimeZone systemTimeZone] secondsFromGMT] sinceDate:createdDateUtc];


Here is what the array looks like which is incorrect as you can see it created my Utc date as my local date and pushed the create date to tomorrow and still using the same time offset, I am so confused


createdDate = "2016-12-25T03:19:38+08:00";
createdDateUtc = "2016-12-24T19:19:38+08:00";

Replies

You are very much in the weeds, alas. First things first, an NSDate represents an absolute point in time as a floating point offset in seconds from the reference date (the beginning of 2001, UTC). NSDate are always UTC; time zones are never involved.

In Foundation time zones are always a presentation issue, which is why you’ll find a

timeZone
property on NSDateFormatter. This defaults to local time but you can change it.

What you should do here depends on your specific requirements. You wrote:

I have the need to store both local time as per users timezone and UTC time in a transaction table using core data

Why store two time strings? If I were in your shoes I’d store:

  • The floating point absolute time offset that NSDate uses internally. You can get this via the

    timeIntervalSinceReferenceDate
    property.
  • An integer local time offset from GMT.

From these two values you can reconstruct the date strings if you need them. And storing these values is is easier, less error prone, and more efficient than storing date strings.

Finally, if you decide to continue storing date strings, make sure you read QA1480 NSDateFormatter and Internet Dates. Your current approach will fail badly if, for example, the user toggles between the Gregorian and Buddhist calendars.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"