1
votes

In api call response I'm getting dates in different timezone. I want to convert it to user's local timezone plus user can select any timezone from the list of ios timezone. This is all local. We would never be sending selected user timezone to server.

And while making any api call lets say i am creating an event with selected start date in a picker. I should send it global timezone not with the user selected timezone because it is local to the app.

Currently I am changing defaultTimeZone on selection so that I get proper current date etc. And using NSDateFormatter with setTimeZone ... [NSTimeZone timeZoneWithName...

Is this a better approach to change defaultTimeZone which is all local to the app ? How should I convert the NSdate back to the global date while sending it to the server ?

1

1 Answers

4
votes

NSDate is a point in time, you might call it absolute time. This time is the same for every place on earth. NSDate does not represent a time that is formatted to the likings of the people at a specific location. This differentiation is very important.

A single NSDate() can have multiple representations in multiple timezones.

To make it more visual, these 5 clocks all represent a single point in time (the NSDate instance):

enter image description here

They just show a different representation of the same point in time.

One could say these clocks are what NSDateFormatter.stringFromDate() is. They turn the absolute point in time into a local representation.

To convert between different timezones you don't change NSDate, you change the timezone of NSDateFormatter. If the date string you get from your server is in UTC, you need a NSDateFormatter which uses UTC as timeZone:

let utcDateFormatter = NSDateFormatter()
utcDateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
utcDateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
utcDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

let serverString = "2015-04-03 12:34:56" // date from server, as date representation in UTC
let date = utcDateFormatter.dateFromString(serverString) // date you got from server, as point in time

To display that server time to your user, you take that NSDate and put it into another dateFormatter:

// display absolute time from server as timezone aware string
let localDateFormatter = NSDateFormatter()
localDateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
localDateFormatter.timeStyle = NSDateFormatterStyle.LongStyle
let localDateString = localDateFormatter.stringFromDate(date)

And if you want to send a date string back to your server, you take a NSDate and put it through your UTC dateFormatter.

// send back time to server
let dateString = utcDateFormatter.stringFromDate(NSDate())