为什么Calendar.date(from:DateComponents)添加时间? [英] Why is Calendar.date(from: DateComponents) adding time?
问题描述
我使用以下代码创建一个 DateComponents
的实例:
let dateComponents = DateComponents(
calendar:.current,
timeZone:Calendar.current.timeZone,
era:nil,
year:nil,
month:nil ,
day:nil,
hour:9,
minute:0,
second:0,
nanosecond:0,
工作日:2,
weekdayOrdinal:nil,
quarter:nil,
weekOfMonth:nil,
weekOfYear:nil,
yearForWeekOfYear:nil)
然后我打印 dateComponents
对象并获取以下(预期)输出:
日历:gregorian(当前)timeZone:欧洲/伦敦(当前)小时:9分钟:0秒:0纳秒:0工作日:2 isLeapMonth:false
紧接着,我打印使用以下代码创建的日期:
print(Calendar.current。日期(从:dateComponents)!)
对于我非常沮丧和彻底的不快乐,输出以下内容:
0001-01-01 09:0 1:15 +0000
在创建之前, date(from:dateComponents)
函数似乎在一分钟内添加到dateComponents感谢您提前提供帮助。
> NSDate
对古代日期有一些奇怪和无证的行为。这个变化似乎在1895年左右发生:
在1890年的一年..< 1900 {
// 1月每年1个@ 9AM
让dateComponents = DateComponents(
日历:.current,
timeZone:Calendar.current.timeZone,
年:年,
月: 1,
日:1,
小时:9)
如果dateComponents.isValidDate {
print(dateComponents.date!)
}
}
我的日历是Gregorian,时区是EDT(UTC-0500)。这是输出:
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 //不正确
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
所以在1895年以前的岁月里,苹果以我的时间增加了17分32秒。您有不同的偏移量,这可能是由于您的区域设置。
我在1895年找不到关于公历的任何历史事件。提到英国开始转用格林尼治标准时间,格林威治天文台在十九世纪九十年代开始调整不列颠群岛的日期/时间标准,这样可能已经占到了这个偏移。也许有人可以深入了解 Date
/ NSDate
的源代码,并计算出来?
如果要使用 DateComponent
存储重复的计划,请使用 nextDate(之后:匹配:matchingPolicy:)
找到下一次出现的日程表:
let dateComponents = DateComponents(calendar:.current,timeZone:.current,hour:9,weekday:2)
//下一个星期一的9AM
let nextOccurance = Calendar.current.nextDate (之后:Date(),匹配:dateComponents,matchingPolicy:.nextTime)!
I create an instance of DateComponents
using the following code:
let dateComponents = DateComponents(
calendar: .current,
timeZone: Calendar.current.timeZone,
era: nil,
year: nil,
month: nil,
day: nil,
hour: 9,
minute: 0,
second: 0,
nanosecond: 0,
weekday: 2,
weekdayOrdinal: nil,
quarter: nil,
weekOfMonth: nil,
weekOfYear: nil,
yearForWeekOfYear: nil)
I then print the dateComponents
object and get the following (expected) output:
calendar: gregorian (current) timeZone: Europe/London (current) hour: 9 minute: 0 second: 0 nanosecond: 0 weekday: 2 isLeapMonth: false
Immediately following this, I print the date created using the following code:
print(Calendar.current.date(from: dateComponents)!)
To my great dismay and thorough unhappiness, the following is outputted:
0001-01-01 09:01:15 +0000
The date(from: dateComponents)
function appears to have added just over a minute to the dateComponents before creating a date from them.
Thanks for any help in advance.
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)!
这篇关于为什么Calendar.date(from:DateComponents)添加时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!