为什么Calendar.date(from:DateComponents)添加时间? [英] Why is Calendar.date(from: DateComponents) adding time?

查看:397
本文介绍了为什么Calendar.date(from:DateComponents)添加时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码创建一个 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆