NSDate
has some strange and undocumented behaviors for ancient dates. The change seems to have happened around 1895:
for year in 1890..<1900 {
// January 1 of each year @ 9AM
let dateComponents = DateComponents(
calendar: .current,
timeZone: Calendar.current.timeZone,
year: year,
month: 1,
day: 1,
hour: 9)
if dateComponents.isValidDate {
print(dateComponents.date!)
}
}
My calendar is Gregorian and timezone is EDT (UTC -0500). This is the output:
1890-01-01 14:17:32 +0000
1891-01-01 14:17:32 +0000
1892-01-01 14:17:32 +0000
1893-01-01 14:17:32 +0000
1894-01-01 14:17:32 +0000 // not correct
1895-01-01 14:00:00 +0000 // correct
1896-01-01 14:00:00 +0000
1897-01-01 14:00:00 +0000
1898-01-01 14:00:00 +0000
1899-01-01 14:00:00 +0000
So for the years prior to 1895, Apple somehow added 17 minutes and 32 second to my time. You got a different offset, which is likely due your locale settings.
I couldn't find anything historical event about the Gregorian calendar in 1895. This question mentions that Britain started to switch over to GMT and the Greenwich Observatory started adjusting date/time standards across the British Isles in the 1890s so that may have accounted for this offset. Perhaps someone can delve into the source code for Date
/ NSDate
and figure it out?
If you want to use DateComponent
to store a repeating schedule, use nextDate(after:matching:matchingPolicy:)
to find the next occurance of your schedule:
let dateComponents = DateComponents(calendar: .current, timeZone: .current, hour: 9, weekday: 2)
// 9AM of the next Monday
let nextOccurance = Calendar.current.nextDate(after: Date(), matching: dateComponents, matchingPolicy: .nextTime)!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…