Reputation: 700
I am having an issue with a date string received from a REST web service and how that is being represented in Swift in different timezones. I have just been able to reproduce this issue, so I am going to relate this specific example.
The information I am getting from the web service is a date-time string and a timezone identifier. In this case, the system is in the America/New_York or Eastern US timezone. I created a playground where I have the following code
let dateFormatString = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
let easternTimeZone = "America/New_York"
let serverDate = "2017-03-01T00:00:00-05:00"
I have a method that takes the date string and the timezone identifier and creates a Date object as follows
func dateForDateString(dateString: String, timeZone: String) -> Date?
{
let formatter = DateFormatter()
if timeZone != ""
{
formatter.timeZone = TimeZone(identifier: timeZone)
}
formatter.dateFormat = dateFormatString
return formatter.date(from: dateString)
}
When I call this method with what's returned from the web service
let easternDate = dateForDateString(dateString: serverDate, timeZone: easternTimeZone)
print("\(easternDate)")
The print
statement outputs Optional(2017-03-01 05:00:00 +0000)
which is expected. No problems yet. The problem happens when the device is in a different timezone and for the sake of this example, I am testing with Pacific time. In the playground, the easternTime
variable shows as Feb 28, 2017, 9:00 PM
. Again, not unexpected.
The date is going to be stored in a Firebase database and I don't care about the time at all. So I end up using the Calendar
method startOfDay
as follows
let myDate = Calendar.current.startOfDay(for: ed)
as you may expect, this returns the Date Feb 28, 2017, 12:00 AM
. Obviously not what I want to store in Firebase. The bottom line is that I need the date to be in the timezone the web service returned.
UPDATE As mentioned in the comments, I also tried to create a Calendar instance and set it's timeZone property to a TimeZone with the identifier received from the server. The code looks like this
var easternCal = Calendar(identifier: .gregorian)
if let etz = TimeZone(identifier: easternTimeZone)
{
easternCal.timeZone = etz
}
if let ed = easternDate
{
let convertedDate = dateToTimeZone(date: ed, toTimezone: easternTimeZone)
let currentCalDate = Calendar.current.startOfDay(for: ed)
let myDate = easternCal.startOfDay(for: ed)
print("\(myDate)")
}
Last night, I could have sworn this didn't work, but when I try it now in the playground, it appears to be working just fine. currentCalDate
is the date I don't want, Feb 28, 2017, 12:00 AM
since it is using the user's Calendar that has the Pacific timezone set. myDate
is correctly showing as Feb 28, 2017, 9:00 PM
, which is printing as 2017-03-01 05:00:00 +0000
, what I have wanted all along.
I think this one is solved.
Upvotes: 1
Views: 684
Reputation: 700
As mentioned in the update to my question, creating a Calendar instance and setting the timeZone
property to the one returned from the back-end solved my problem.
Upvotes: 1