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

Swift Calendar重设同值firstWeekday后周数计算异常回退问题

问题根因

这是Foundation框架Calendar类型长期存在的实现缺陷,触发逻辑稳定可复现,和开发环境、系统版本无直接关联:

  • 使用.iso8601标识符初始化Calendar时,内部会维护两套和周计算相关的值:一套是对外暴露的公开属性值,另一套是日期计算专用的内部缓存值,初始状态下两者保持一致:firstWeekday = 2(周一为周起始日)、minimumDaysInFirstWeek = 4(首周至少包含4天,符合ISO8601标准)。
  • 单独修改minimumDaysInFirstWeek属性时,公开属性和内部计算缓存会同步更新,因此步骤1修改后周数计算结果符合预期。
  • 只要对firstWeekday执行赋值操作,无论传入的值和当前公开属性值是否完全一致,都会触发内部的参数联动逻辑:自动把计算缓存中的minimumDaysInFirstWeek重置为当前历法的默认值4,但这个重置操作不会同步更新对外公开的minimumDaysInFirstWeek属性。
    这就导致步骤2出现了看似矛盾的现象:打印公开属性看到minimumDaysInFirstWeek还是1,实际周数计算用的是缓存里被重置为4的值,结果直接回退到初始状态。
规避方案

两种方案都可以彻底绕过这个问题:

  • 调整属性赋值顺序:只要修改过firstWeekday(哪怕赋的值和默认值相同),立刻重新赋值一次minimumDaysInFirstWeek,强制内部计算缓存同步为你设置的值。修正后的步骤2代码如下:
print("\n*** Step 2 修正后 ***")
calendar.firstWeekday = 2
calendar.minimumDaysInFirstWeek = 1 // 新增该行,强制同步缓存值
print("firstWeekday : \(calendar.firstWeekday)")
print("minimumDaysInFirstWeek : \(calendar.minimumDaysInFirstWeek)")
print("weekOfMonth : \(calendar.component(.weekOfMonth, from: date!))")
print("weekOfYear : \(calendar.component(.weekOfYear, from: date!))")

运行后weekOfMonth和weekOfYear都会正确返回1。

  • 如果不需要修改周起始日,不要对firstWeekday做任何重复赋值操作,哪怕值和默认值完全一致,从根源上避免触发错误的内部重置逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:27:18