提问人:Jim Sutcliffe 提问时间:2/26/2022 更新时间:3/6/2022 访问量:115
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解码时如何解决这个问题,因为我无法知道我的数据将包含哪些日期?到目前为止,我只是在代码中将其用作字符串,但这不会持续很长时间。
答:
0赞
Jim Sutcliffe
3/6/2022
#1
好的,答案是,由于铁路的使用需要更好的时间,因此许多州和省在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 的数据中。这迫使一切都到了格林威治标准时间,而格林威治标准时间不会受到这个问题的影响。
感谢大家的帮助
评论
0赞
Sulthan
3/6/2022
您也可以在格式化程序上设置特定的时区(例如)。另请注意,这将为您做到这一点。TimeZone(secondsFromGMT: 0)
ISO8601DateFormatter
0赞
Jim Sutcliffe
3/6/2022
谢谢 Sulthan - 这似乎更干净,所以会尝试一下。
评论