80 年代的 4 月 1 日未能在 iOS 10.0 中解析
我发现 DateFormatter date(from:)
方法无法解析几个特定的日期.方法返回 1981-1984 年 4 月 1 日的 nil
.是Foundation的bug吗?我们可以做些什么来解析这些日期?
I found that DateFormatter date(from:)
method can't parse a couple of specific dates. Method returns nil
for the 1st april of 1981-1984 years. Is it a bug of Foundation? What can we do to perform parsing of such dates?
Xcode 8.0,iOS SDK 10.0.这是一个简短的操场示例的屏幕截图:
Xcode 8.0, iOS SDK 10.0. Here is a screenshot of a short playground example:
如果夏令时刚好开始,就会出现这个问题午夜,就像 1981 年至 1984 年莫斯科的情况一样(参见例如 俄罗斯莫斯科 (Moskva) 的时钟变化.
This problem occurs if daylight saving time starts exactly on midnight, as it was the case in Moscow in the years 1981–1984 (see for example Clock Changes in Moscow, Russia (Moskva)).
这也在
例如,在 1984 年 4 月 1 日午夜,时钟向前调整了一个小时,这意味着日期1984-04-01 00:00"该时区不存在:
For example, at midnight of April 1st 1984, the clocks were adjusted one hour forward, which means that the date "1984-04-01 00:00" does not exist in that timezone:
let dFmt = DateFormatter()
dFmt.dateFormat = "yyyy-MM-dd"
dFmt.timeZone = TimeZone(identifier: "Europe/Moscow")
print(dFmt.date(from: "1984-04-01")) // nil
作为一种解决方案,您可以告诉日期格式化程序宽松":
As a solution, you can tell the date formatter to be "lenient":
dFmt.isLenient = true
然后它将返回当天的第一个有效日期:
and then it will return the first valid date on that day:
dFmt.isLenient = true
if let date = dFmt.date(from: "1984-04-01") {
dFmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(dFmt.string(from: date))
}
// 1984-04-01 01:00:00
另一种解决方案由 rob mayoff 给出,这是为了使日期格式化程序使用 noon 而不是午夜作为默认日期.这是 rob 的代码从 Objective-C 到 Swift 的翻译:
A different solution was given by rob mayoff, which is to make the date formatter use noon instead of midnight as the default date. Here is a translation of rob's code from Objective-C to Swift:
let noon = DateComponents(calendar: dFmt.calendar, timeZone: dFmt.timeZone,
year: 2001, month: 1, day: 1, hour: 12, minute: 0, second: 0)
dFmt.defaultDate = noon.date
if let date = dFmt.date(from: "1984-04-01") {
dFmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(dFmt.string(from: date))
}
// 1984-04-01 12:00:00