DateFormatter.localizedString is broken for some of the dates

徘徊边缘 提交于 2019-12-14 04:04:12

问题


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)
}


来源:https://stackoverflow.com/questions/46320207/dateformatter-localizedstring-is-broken-for-some-of-the-dates

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