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实例:
- 如果需要跟随系统时区计算,直接使用同一个
Calendar实例即可:
func daysInMonth() -> Int { let calendar = Calendar.current return calendar.range(of: .day, in: .month, for: self)?.count ?? 0 }
- 如果需要固定用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
相关产品推荐
相关产品推荐

