DateFormatter.localizedString is broken for some o

2019-08-23 07:17发布

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:

enter image description here enter image description here enter image description here enter image description here

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条回答
别忘想泡老子
2楼-- · 2019-08-23 07:53

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)
}
查看更多
登录 后发表回答