我正试图将Date
转换为DateComponents
,更改一些属性,并获得新的Date
。我写了下面的代码:
import Foundation
var components = Calendar.current.dateComponents(in: .current, from: Date())
components.day = 7
components.month = 3
components.year = 1900
DateFormatter.localizedString(from: components.date!, dateStyle: .long, timeStyle: .long)
我在iOS 15.0上的iOS模拟器上的America/Denver
时区/区域以及运行最新macOS Big Sur和Xcode 13.0的Mac上的Swift REPL中测试了这一点,在这两个地方,我在撰写本文时得到了大约以下输出:
March 7, 2021 at 9:38:13 AM MST
除了年份之外,这一切都在预料之中。我已经明确地将年份设置为1900
,但是输出中的年份是2021
。我如何使DateComponents
在生成日期时尊重年份,或者我如何手动做同样的事情,以便它实际工作?
如果你得到all组件从日期与dateComponents(in:from:)
,你必须也设置相应的yearForWeekOfYear
components.yearForWeekOfYear = 1900
或者只指定您真正需要的日期和时间组件,包括calendar
和timeZone
,例如
var components = Calendar.current.dateComponents([.calendar, .timeZone, .year, .month, .day, .hour, .minute, .second], from: Date())
components.day = 7
components.month = 3
components.year = 1900
DateFormatter.localizedString(from: components.date!, dateStyle: .long, timeStyle: .long)
注意,您将获得所有日期组件,包括weekOfYear
、weekOfMonth
、dayOfWeek
,以及最重要的yearForWeekOfYear
。当您将日期组件设置为1900-03-07时,您也没有正确设置所有这些组件,并且当从具有此类冲突组件的DateComponents
解析Date
时,算法恰好更倾向于从yearForWeekOfYear
获得的年份。
如果您将这些字段设置为nil
,您将得到预期的结果:
var components = Calendar.current.dateComponents(in: .current, from: Date())
components.day = 7
components.month = 3
components.year = 1900
components.yearForWeekOfYear = nil
在日期组件中仍然会有冲突,虽然这不会导致崩溃,但我不确定这种行为将来是否会改变。我建议您只获取所需的组件。例如:
var components = Calendar.current.dateComponents([
.calendar, .timeZone, .era, .year, .month, .day, .hour, .minute, .second, .nanosecond
], from: Date())