|
// macOS 10.12.1 or iOS 10, Swift 3.0.1 |
|
|
|
import Foundation |
|
|
|
var calendar = Calendar(identifier: .gregorian) |
|
// GMT+1 (GMT+2 under daylight saving) |
|
calendar.timeZone = TimeZone(identifier: "Europe/Berlin")! |
|
|
|
// 2016-10-30 02:30:00 +02:00 |
|
// Europe/Berlin switched from daylight saving to winter time on this date, i.e. on 2016-10-30 03:00:00 +02:00 the clock was moved back by one hour. |
|
let startDate = calendar.date(from: DateComponents(year: 2016, month: 10, day: 30, hour: 2, minute: 30, second: 0))! |
|
print("startDate:", startDate) // startDate: 2016-10-30 00:30:00 +0000 |
|
|
|
// Verify that nanoseconds are 0 for this date |
|
let comps = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: startDate) |
|
assert(comps.nanosecond == 0) // passes |
|
|
|
// Find the next full hour, i.e. the next date where minute == 0 and second == 0. |
|
// Two variants: |
|
// 1) Pass date components minute, second, and nanosecond |
|
let nextDate1 = calendar.nextDate(after: startDate, matching: DateComponents(minute: 0, second: 0, nanosecond: 0), matchingPolicy: .strict, repeatedTimePolicy: .first)! |
|
// 2) Pass only minute and second |
|
let nextDate2 = calendar.nextDate(after: startDate, matching: DateComponents(minute: 0, second: 0), matchingPolicy: .strict, repeatedTimePolicy: .first)! |
|
|
|
// These should be equal! |
|
print("nextDate1:", nextDate1) // nextDate1: 2016-10-30 02:00:00 +0000 |
|
print("nextDate2:", nextDate2) // nextDate2: 2016-10-30 01:00:00 +0000 |
|
assert(nextDate1 == nextDate2) // should pass, but fails |
|
|
|
// I tried various variations for matchingPolicy and repeatedTimePolicy, but always got the same result. |