首页 > 解决方案 > 用 12 月的时间获取月初和月底

问题描述

正如标题所示,我正在尝试使用 12 月的时间组件来获取月份的开始和结束。我确定我错过了与 TimeZones 相关的明显内容,但在 PST 时区的两个日期中,我似乎无法获得相同的年份。

这是我如何获得月份和日期的开始:

注意:如果您在 swift REPL 中尝试此操作,则会出现显示 nil 结果的错误,即使变量具有非 nil 值,请使用printordebugPrint来显示该值。

let cal = Calendar.current
let startOfMonth = cal.startOfDay(for: cal.date(from: DateComponents(year: 2020, month: 12, day: 1))!)

以下是我计算一天结束时间的方法:

let startOfNextMonth = cal.date(byAdding: DateComponents(month: 1), to: startOfMonth)!
let endOfMonth = cal.date(byAdding: DateComponents(second: -1), to: startOfNextMonth)!

此时startOfMonth具有值:Optional(2020-12-01 08:00:00 +0000)并且endOfMonth具有值Optional(2021-01-01 07:59:59 +0000)

这看起来很好而且很花哨,因为时间是以 GMT (UTC) 打印的,如果我减去 8 小时endOfMonth,它最终会像Optional(2020-12-31 23:59:59 +0000)

但是,格式化endOfMonth日期时出现问题,即使我将 TimeZone 设置为,"America/Los_Angeles"我仍然会得到年份值 as2021而不是 as 2020,这就是我创建格式化程序的方式:

let fmt = DateFormatter()
fmt.timeZone = .current // "America/Los_Angeles"
fmt.dateFormat = "d/Y"

fmt.string(from: endOfMonth!) // $R13: String = "31/2021"

发生了什么事?,转换为默认时区不会产生 2020 年吗?

标签: swiftdatedatetimensdateformatter

解决方案


在将 formatterdateStyle属性设置为.long并获得正确的打印年份(虽然不是我想要的格式)后,我意识到问题可能出在dateFormat.

在阅读了更多文档后,我找到了格式说明符的链接

最终我发现说明Y符本质上y是“一年中的一周”,而说明符是“时代”。

使用以下解决了我的问题:

let formatter = DateFormatter()
formatter.dateFormat = "d/y"
formatter.string(from: endOfMonth!) // $R1: String = "31/2020"

推荐阅读