DateFormatter wrong time output when a different month is selected

47 views Asked by At

I have a separate DatePicker and TimePicker component in my app.

Once the user has selected both the desired Date and Time, I construct a new Date object like this:

let timeStamp = Date(year: selectedDate.year, month: selectedDate.month, day: selectedDate.day, hour: selectedTime.hour, minute: selectedTime.minute)

I then use DateFormatter to output the exact time that the user has selected like this:

let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
formatter.string(from: timeStamp)

Now I have a very weird bug where sometimes time output will be correct (time will be displayed in UTC+2) and sometimes it'll be incorrect (time will be displayed in UTC+1) and I have absolutely no idea what could be causing this.

Example 1 (correct output):

User selects: May 26, 2020 - 18:38
Date ISO output: "2020-05-26T16:38:00Z" 
DateFormatter output: "18:38"   

This is the correct output

Example 2 (wrong output):

User selects: March 26, 2020 - 18:38
Date ISO output: "2020-03-26T16:38:00Z"
DateFormatter output: "17:38"       

This is not the correct output. Time should be 18:38 like in the above example.

Someone please tell me how is this possible? Literally the only difference is user picked March instead of May (different month) and that for some reason confuses the DateFormatter, so Time output is in a different timezone.

I am using SwiftDate to work with dates in general.

2

There are 2 answers

1
Robin Bork On

That is probably because in May daylight saving is in effect and the difference to UTC changes from +1 to +2 hours

You can use the current TimeZone and add configure your DateFormatter with it

let timezone = TimeZone.current
dateFormatter.timeZone = timezone

That should make sure that you always use the same timezone that is currently used by your device

0
саня On

Set correct formatter.locale, you can try Locale(identifier: "en_US_POSIX") or try to use formatter.timeZone property. Maybe TimeZone.current or TimeZone(secondsFromGMT: 0) will fix your problem