1895 年 1 月 1 日字符串错误中的 DateFormatter

DateFormatter from String bug for January 1, 1895

我在 DateFormatter 的 .date(from: String) 函数中发现了最奇怪的错误,因为它似乎并不特别喜欢 1895-01-01。工作前后的日期,但那一天的日期为零。

我可以使用 1894-12-31 并添加一天来表明底层 NSDate 没问题——似乎只是 DateFormatter 转换。

这里是用于演示的 playground 代码。

import Foundation

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"

let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
let date1 = fmt.date(from: "1894-12-31")
let date2 = fmt.date(from: "1895-01-01")
let date3 = fmt.date(from: "1895-01-02")
let calcDate2 = date1?.addingTimeInterval(86400)

print("Date 1: \(date1)")
print("Date 2: \(date2)")
print("Date 3: \(date3)")
print("\nCalculated Date 2: \(calcDate2)")

输出为:

Date 1: Optional(1894-12-31 05:17:32 +0000)
Date 2: nil
Date 3: Optional(1895-01-02 05:00:00 +0000)

Calculated Date 2: Optional(1895-01-01 05:17:32 +0000)

我还发现了一个先前的问题 关于在 1895 年左右添加时间的奇怪行为,所以这可能有某种关联?

这是一个错误吗?知道在 JSON 解码时如何解决这个问题吗,因为我不知道我的数据将包含什么日期?到目前为止,我只是在我的代码中将它用作字符串,但这不会长期有效。

好的,答案是因为铁路的使用需要更好的时间来保持许多州和省在 1895 年采用了弗莱明几年前建议的时区。

这建立了太平洋、山地、中部和东部(我所在的地方)时区。因此,需要对 00:17:32 东部进行调整。所以时钟在新年从 23:59:59 变为 00:17:32。

这可以用以下代码显示:

import Foundation

let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"

let date1 = fmt.date(from: "1894-12-31 23:59:59")
let date2 = fmt.date(from: "1895-01-01 00:00:00")
let date3 = fmt.date(from: "1895-01-01 00:17:31")
let date4 = fmt.date(from: "1895-01-01 00:17:32")

print("Date 1 (1 sec to midnight): \(date1)")
print("Date 2 (midnight): \(date2)"). // invalid
print("Date 3 (17:31 past midnight): \(date3)"). // invalid
print("Date 4 (17:32 past midnight: \(date4)")

let calc1 = date1?.addingTimeInterval(1)
print("Date 1 + 1 second (midnight): \(calc1)")

输出是(对于 EST):

Date 1 (1 sec to midnight): Optional(1895-01-01 05:17:31 +0000)
Date 2 (midnight): nil
Date 3 (17:31 past midnight): nil
Date 4 (17:32 past midnight: Optional(1895-01-01 05:17:32 +0000)
Date 1 + 1 second (midnight): Optional(1895-01-01 05:17:32 +0000)

感谢所有的帮助。

实际使用的解决方案是将“Z”时区添加到字符串格式的末尾,同样将“Z”附加到我正在调用的 API 的数据中。这迫使它全部进入 GMT,而不会遇到这个问题。

感谢大家的协助