MwcsMac
MwcsMac

Reputation: 7168

Swift json time value to local time zone

I have a json request that can produce two different types of time values. Both ways it is in UTC time but I need to convert it to local time.

2015-12-01T13:05:33+00:00

or

1:05:33 PM

My attempt.

let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle //Set time style
dateFormatter.timeZone = NSTimeZone()
let localDate: NSDate? = dateFormatter.dateFromString(time1)
print(localDate)

This what I get a as a result. 2000-01-01 19:05:33 +0000 if I use the 1:05:18 PM value.

The line for getting the json value.

let time1 = json["results"]["time1"].string!

Upvotes: 3

Views: 2308

Answers (2)

Rob
Rob

Reputation: 437482

OK, a couple of things things:

  1. Parsing that RFC 3339/ISO 8601 string:

    let string = "2015-12-01T13:05:33+00:00"
    
    let rfc3339Formatter = NSDateFormatter()
    rfc3339Formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    rfc3339Formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    let date = rfc3339Formatter.dateFromString(string)
    

    Note, I've set the locale (as per Technical Q&A 1480). But because the date string included time zone information, I can use the Z formatter character so that the time zone is correctly interpreted.

  2. But NSDate objects do not have a time zone associated with them. In fact, if we do print(date) that we successfully parsed in the previous step, it will show us that NSDate in GMT/UTC, even if that original string was in a different time zone.

    A timezone is only meaningful when you use a formatter to convert this NSDate back to a new string to be presented to the user. So we can use a separate formatter to create the output string:

    let userDateFormatter = NSDateFormatter()
    userDateFormatter.dateStyle = .MediumStyle
    userDateFormatter.timeStyle = .MediumStyle
    let outputString = userDateFormatter.stringFromDate(date!)
    

    Because this doesn't specify a time zone, it will create a string in the user's local time zone. And because we don't override the locale and use .dateStyle and .timeStyle, it will display it using the device's current localization settings when creating a string to be presented to the end-user.

  3. Now, if you really are receiving a time in UTC (without the time zone included?! yikes, that's a really poor design to see that in JSON, IMHO), then you have to specify time zones:

    let string = "1:05:33 PM"
    
    let utcTimeStringFormatter = NSDateFormatter()
    utcTimeStringFormatter.dateFormat = "hh:mm:ss a"
    utcTimeStringFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
    let time = utcTimeStringFormatter.dateFromString(string)
    

    Now that we have time, a NSDate containing the time represented by that string. But again, NSDate objects, themselves, don't have a time zone. Only when we convert that back to a string for the end user will we see the time in the local time zone:

    let userTimeFormatter = NSDateFormatter()
    userTimeFormatter.timeStyle = .MediumStyle
    let outputString = userTimeFormatter.stringFromDate(time!)
    

Upvotes: 1

Sohel L.
Sohel L.

Reputation: 9540

You can just try by setting your local timeZone or by setting GMT

formatter.timeZone = NSTimeZone.localTimeZone()

OR

formatter.timeZone = NSTimeZone(abbreviation: "GMT")

Let me know, if you are still facing the error!

Upvotes: 0

Related Questions