快速日历日期通过将小时设置为0更改日

时间:2018-04-19 18:03:10

标签: swift nsdate

如果我运行以下代码:

let date = Date()
let midnight = Calendar.current.date(bySetting: .hour, value: 0, of: date)!
let difference = Int64(midnight.timeIntervalSince(date))
print(String(difference))

差异是大约13个小时的正值(因为当地时间大约是上午11点)。但是,我预计差异将是负11小时;因为我将.hour值设置为0我希望时间会向后移动,而不是向前移动。

我希望明天能用这段代码找到午夜:

let midnight = Calendar.current.date(bySetting: .hour, value: 0, of:
   Calendar.current.date(byAdding: .day, value: 1, to: date)!)!

但是这给了+37小时而不是+13。

目前的行为实际上是我想要的行为(我想知道明天午夜之前的时间)。但是,我想了解为什么会发生这种情况,特别是我想确保明天午夜的这种方法无论时区如何都能奏效。谢谢!

编辑:注意,我只关心午夜的时间,这就是为什么我在找到午夜时不会改变分钟或秒值。

2 个答案:

答案 0 :(得分:5)

我认为这是预期的,正如它在documentation中所说的那样,

  

该算法将尝试生成下一个更大的结果   组件到给定的组件(顶部有一个映射表)   这份文件)。因此,对于“设置为星期四”的例子,找到   星期四在给定日期所在的周(可能是一个   向前或向后移动,而不一定是最近的星期四)。   要更好地控制确切的行为,请使用   nextDate(后:匹配:matchingPolicy:行为:方向:)

使用nextDate(after date: Date, matching components: DateComponents, matchingPolicy: Calendar.MatchingPolicy, repeatedTimePolicy: Calendar.RepeatedTimePolicy = default, direction: Calendar.SearchDirection = default) -> Date?会产生正确的结果,如您所料。

示例在这里,

let calendar = Calendar.current
var hourComponent = DateComponents()
hourComponent.hour = 0

let midnightSameDay = calendar.nextDate(after: date,
                                        matching: hourComponent,
                                        matchingPolicy: .nextTime,
                                        direction: .backward)
print(mightnightSameDay) // 2018-04-19 00:00:00 +0000

let midnightNextDay = calendar.nextDate(after: date,
                                        matching: hourComponent,
                                        matchingPolicy: .nextTime,
                                        direction: .forward)
print(mightnightNextDay) // 2018-04-20 00:00:00 +0000

还有另一种可以用于此的方法,它使用搜索方向和匹配策略,

let midnightSameDay = calendar.date(bySettingHour: 0,
                                    minute: 0,
                                    second: 0,
                                    of: date,
                                    direction: .backward)

答案 1 :(得分:1)

date(bySetting:value:of)做出最佳猜测,即#34;实施定义"根据新参数创建新的Date。通过将hour设置为0 - 有时这会在相同的日历日创建Date,并相应地设置hour,有时新的Date会明天。听起来并不能说明你需要的可靠性,但希望它可以回答你的问题。

文档更深入:

https://developer.apple.com/documentation/foundation/calendar/2292915-date