问题描述
在具有以下 Swift 代码的 Xcode 操场中,我得到了注释输出。给定 MST TimeZone 对象和该 MST TimeZone 的 MDT TimeZone 中的日期,我没有收到预期的 MDT TimeZone 缩写输出。我对这个函数有什么不理解,以及如何获得所需的输出,以确定给定日期在当前示例 MST 时区中的两个可能时区中的哪一个?
// Daylight saving time (MDT) 2021 in Colorado began at 2:00 AM on Sunday,march 14
let mstDate = Date(timeIntervalSinceReferenceDate: 636327068) // "Mar 1,2021 at 2:31 PM"
let mdtDate = Date(timeIntervalSinceReferenceDate: 637709468) // "Mar 17,2021 at 3:31 PM"
let mstTimeZone = TimeZone(abbreviation: "MST")!
let mdtTimeZone = TimeZone(abbreviation: "MDT")!
mstTimeZone.abbreviation(for: mstDate) // expected MST,got MST
mstTimeZone.abbreviation(for: mdtDate) // expected MDT,got *****MST*****?
mdtTimeZone.abbreviation(for: mstDate) // expected MST,got MST
mdtTimeZone.abbreviation(for: mdtDate) // expected MDT,got MDT
解决方法
不要依赖时区缩写。 MST 被解释为“山地标准时间”,但被解释为亚利桑那州凤凰城(“美国/凤凰城”)而不是科罗拉多州丹佛市(“美国/丹佛”)。您应该始终使用时区标识符而不是含糊不清的缩写。时区标识符不会根据日期改变。您需要检查所需日期/时区是否为夏令时,并根据它获取时区本地化名称:
extension TimeZone {
static let denverCO = Self(identifier: "America/Denver")!
func localizedName(for date: Date) -> String { localizedName(for: isDaylightSavingTime(for: date) ? .daylightSaving : .standard,locale: .current) ?? "" }
func localizedNameShort(for date: Date) -> String { localizedName(for: isDaylightSavingTime(for: date) ? .shortDaylightSaving : .shortStandard,locale: .current) ?? "" }
}
let mst = Date(timeIntervalSinceReferenceDate: 636327068) // "Mar 1,2021 at 2:31 PM"
let mdt = Date(timeIntervalSinceReferenceDate: 637709468) // "Mar 17,2021 at 3:31 PM"
TimeZone.denverCO.localizedName(for: mst) // "Mountain Standard Time"
TimeZone.denverCO.localizedName(for: mdt) // "Mountain Daylight Time"
TimeZone.denverCO.localizedNameShort(for: mst) // "MST"
TimeZone.denverCO.localizedNameShort(for: mdt) // "MDT"