DateComponentsFormatter 不适用于过去很久的日期
DateComponentsFormatter not working with dates far in the past
我正在使用内置的 DateComponentsFormatter 来计算当前日期和另一个日期之间的年数。如果日期过去太远,例如 1940,则返回的单位是错误的:
let dateComponents = DateComponents(year: 1940, month: 1, day: 2, hour: 1, minute: 1, second: 1)
let date = Calendar.current.date(from: dateComponents)!
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.year]
dateComponentsFormatter.unitsStyle = .full
print(dateComponentsFormatter.string(from: abs(date.timeIntervalSinceNow)))
这会打印出 -58 years
,这是不正确的。这是苹果的错误吗?我做错了什么吗?
这是 DateComponentsFormatter
实现中的错误。
他们显然在内部使用 Int32 来表示时间间隔。
我运行遇到了同样的问题,很容易复现:
let interval: TimeInterval = ... some number here
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .abbreviated
print(formatter.string(from: interval) ?? "")
这应该只是输出秒数,没有任何特殊的计算。
即使这样也只能按预期工作,直到 2147483647(恰好是 Int32.max)。上面的所有内容都会溢出并产生不正确的结果。
这个最大 "supported" 秒数是 68y 2w 4d 3h 14m 7s,这解释了为什么你也看到它。
UPD
有人已经提交了雷达:http://www.openradar.me/32513237 并在那里提到了一个解决方法,而且它有效!
在你的情况下,将改为使用:
let date = Calendar.current.date(from: dateComponents)!
let now = Date()
dateComponentsFormatter.string(from: date, to: now)
我正在使用内置的 DateComponentsFormatter 来计算当前日期和另一个日期之间的年数。如果日期过去太远,例如 1940,则返回的单位是错误的:
let dateComponents = DateComponents(year: 1940, month: 1, day: 2, hour: 1, minute: 1, second: 1)
let date = Calendar.current.date(from: dateComponents)!
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.year]
dateComponentsFormatter.unitsStyle = .full
print(dateComponentsFormatter.string(from: abs(date.timeIntervalSinceNow)))
这会打印出 -58 years
,这是不正确的。这是苹果的错误吗?我做错了什么吗?
这是 DateComponentsFormatter
实现中的错误。
他们显然在内部使用 Int32 来表示时间间隔。
我运行遇到了同样的问题,很容易复现:
let interval: TimeInterval = ... some number here
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .abbreviated
print(formatter.string(from: interval) ?? "")
这应该只是输出秒数,没有任何特殊的计算。 即使这样也只能按预期工作,直到 2147483647(恰好是 Int32.max)。上面的所有内容都会溢出并产生不正确的结果。
这个最大 "supported" 秒数是 68y 2w 4d 3h 14m 7s,这解释了为什么你也看到它。
UPD
有人已经提交了雷达:http://www.openradar.me/32513237 并在那里提到了一个解决方法,而且它有效!
在你的情况下,将改为使用:
let date = Calendar.current.date(from: dateComponents)!
let now = Date()
dateComponentsFormatter.string(from: date, to: now)