You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决ISO8601DateFormatter处理年初日期返回上一年的问题

新年首日ISO8601返回上一年份问题的解决方法

问题根源

该现象是ISO8601日历的周年(Week Year) 规则导致的正常结果:
ISO8601日历的year组件默认返回周年,判定规则为每年第一个包含周四的周为第1周,1978年1月1日为周日,属于1977年的最后一周,因此返回的周年为1977,和实际自然年不一致。

解决方法

无需修改日期、无需加偏移量,仅调整日历类型即可获取正确自然年:
改用格里高利(公历)日历获取日期组件,同时保证日历和日期解析器的时区完全一致,避免跨时区偏移。

修正后代码示例

import Foundation

let datestring = "1978/1/1"
var formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(abbreviation: "UTC")
formatter.formatOptions = [.withFullDate]
let date2 = formatter.date(from: datestring) ?? Date()
print(date2)

// 改用公历日历,时区和解析器保持一致
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = formatter.timeZone!

var year = calendar.component(.year, from: date2)
var month = calendar.component(.month, from: date2)
var day = calendar.component(.day, from: date2)
var era = calendar.component(.era, from: date2)
print("year \(year) month \(month) day \(day) era: \(era)")

// 输出结果:
// 1978-01-01 00:00:00 +0000
// year 1978 month 1 day 1 era: 1

注意事项

  • 如果业务必须使用ISO8601日历体系,不要使用.year组件,若需要对应自然年请仍通过公历日历获取,避免和周历规则冲突。
  • 日期解析和组件读取的时区必须统一,否则零点日期容易出现跨天偏移,导致年份/月份/日期错误。

内容的提问来源于stack exchange,提问作者jonkimsr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 09:54:04