通过将小时设置为0更改日期来设置Swift日历日期

kme*_*l96 2 nsdate swift

如果我运行以下代码:

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

差异是大约13小时的正值(因为现在本地时间是大约11 AM)。但是,我希望两者之间的差值为11小时。由于我将.hour值设置为,0我希望时间会向后移动,而不是向前移动。

我希望明天必须使用以下代码找到午夜:

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

但这将使+37小时而不是+13小时。

当前的行为实际上是我想要的行为(我想知道直到明天午夜的时间)。但是,我想了解为什么会发生这种情况,尤其是要确保这种找到明天午夜的方法在任何时区都适用。谢谢!

编辑:请注意,我只关心午夜之前的时间,这就是为什么我不更改午夜时的分钟或秒值的原因。

San*_*eep 6

我认为这是文档中所说的,

该算法将尝试产生一个结果,该结果位于给定组件的下一个更大的组件中(此文档顶部的表中有此映射)。因此,对于“设置为星期四”的示例,找到给定日期所在的周中的星期四(可以向前或向后移动,不一定是最近的星期四)。要对确切行为进行更多控制,请使用nextDate(after:matching:matchingPolicy:behavior:direction :)。

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
Run Code Online (Sandbox Code Playgroud)

您还可以使用另一种方法来使用搜索方向和匹配策略,

let midnightSameDay = calendar.date(bySettingHour: 0,
                                    minute: 0,
                                    second: 0,
                                    of: date,
                                    direction: .backward)
Run Code Online (Sandbox Code Playgroud)