DateFormatter.localizedString is broken for some of the dates

匿名 (未验证) 提交于 2019-12-03 01:44:01

问题:

This is what I do when picker changes:

extension Date {     var fromCurrentToUTC: Date {         return addingTimeInterval(-TimeInterval(TimeZone.current.secondsFromGMT()))     } }       var title = "--"  if let date = datePickerView.date?.fromCurrentToUTC {     title = DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .none) }  print("-----") print(datePickerView.date!) print(title) print(TimeZone.current) print(datePickerView.date!.timeIntervalSince1970)  dateTimeSegmentControl.setTitle(title, forSegmentAt: 0)

And this is how it looks for the dates:

Assuming. Everything is fine for the dates before 6th November, and everything is off after 6th November. Why?

update:

That critical date is different for every time zone I use. For example:

Warsaw (+0200) the date is 30 October Chicago (-0500) the date is 6th November

The ordered prints:

----- 2017-11-04 00:00:00 +0000 4 Nov 2017 America/New_York (current) 1509753600.0 ----- 2017-11-05 00:00:00 +0000 5 Nov 2017 America/New_York (current) 1509840000.0 ----- 2017-11-06 00:00:00 +0000 5 Nov 2017 America/New_York (current) 1509926400.0 ----- 2017-11-07 00:00:00 +0000 6 Nov 2017 America/New_York (current) 1510012800.0 

回答1:

In your function

extension Date {     var fromCurrentToUTC: Date {         return addingTimeInterval(-TimeInterval(TimeZone.current.secondsFromGMT()))     } } 

the GMT offset of the current date is subtracted, not by the GMT offset of the date to be adjusted. Therefore you get a wrong result if the date to be adjusted is in a DST period and the current date is not, or vice versa.

That can be fixed by using

extension Date {     var fromCurrentToUTC: Date {         return addingTimeInterval(-TimeInterval(TimeZone.current.secondsFromGMT(for: self)))     } } 

instead. However, a better solution would be to set the timezone of the date formatter to UTC, instead of adjusting the date:

if let date = datePickerView.date {     let fmt = DateFormatter()     fmt.dateStyle = .medium     fmt.timeStyle = .none     fmt.timeZone = TimeZone(secondsFromGMT: 0)     let title = fmt.string(from: date)     print(title) }


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!