DateComponents 似乎不尊重年份

DateComponents doesn't seem to honor year

我正在尝试将 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)

我在 America/Denver 时间 zone/locale 在 iOS 模拟器上测试了 iOS 15.0 以及 Swift REPL 在我的Mac 运行 最新的 macOS Big Sur 和 Xcode 13.0,在撰写本文时,在这两个地方,我大约得到以下输出:

March 7, 2021 at 9:38:13 AM MST

一切都符合预期,除了年份。我已将年份明确设置为 1900,但输出中的年份是 2021。我怎样才能在生成日期时让 DateComponents 尊重年份,或者我怎样才能手动做同样的事情才能真正起作用?

如果您从 dateComponents(in:from:) 的日期获得 所有 个组件,您还必须相应地设置 yearForWeekOfYear

components.yearForWeekOfYear = 1900

或者仅指定日期和时间部分,包括您真正需要的 calendartimeZone,例如

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)

请注意,您将获得 所有 日期组件,包括 weekOfYearweekOfMonthdayOfWeek,最重要的是,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())