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

Swift 计算当月天数方法晚10点后返回错误值问题求助

Swift获取当月天数异常原因分析

根本原因

这个问题的核心是时区偏移导致的跨月判定偏差,具体逻辑如下:

  • Swift中的Date类型本质是UTC时间戳,本身不携带时区信息,你直接打印Date输出的是UTC时区的时间,也就是你看到的2021-11-30 23:46:29 +0000。
  • 你调用的Calendar.current会绑定当前系统的时区,计算月份、天数时会先把UTC时间转换为当地时区的时间再做判定。
  • 你设置的系统当地时间是11月30日23:46,此时对应的UTC时间是2021-11-30 23:46:29,如果你所在的时区是UTC正偏移(比如UTC+1、UTC+2等),转换为当地时间后已经进入了12月1日的区间,因此Calendar.current会判定该时间属于12月,计算得到12月的总天数31,同时取月份得到12。
  • 晚10点前运行正常的原因是:此时对应的UTC时间转换为当地时间后还处于11月的区间,判定逻辑符合预期。
  • 你提到的“日属性值正确”大概率是因为你的day扩展属性是直接读取UTC时间的日期,和Calendar.current用的当地时区不统一,才出现了“日期是30、月份是12”的矛盾输出。

修复方案

所有日期相关计算统一时区来源,避免混用不同时区的Calendar实例:

  1. 如果需要跟随系统时区计算,直接使用同一个Calendar实例即可:
func daysInMonth() -> Int {
    let calendar = Calendar.current
    return calendar.range(of: .day, in: .month, for: self)?.count ?? 0
}
  1. 如果需要固定用UTC时区计算,显式指定Calendar的时区:
func daysInMonthUTC() -> Int {
    var calendar = Calendar(identifier: .gregorian)
    calendar.timeZone = TimeZone(secondsFromGMT: 0)!
    return calendar.range(of: .day, in: .month, for: self)?.count ?? 0
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:15:01