Skip to content

Instantly share code, notes, and snippets.

@mrackwitz
Created November 4, 2017 19:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrackwitz/e91892f3a22c5e0a797e60f8d7e75127 to your computer and use it in GitHub Desktop.
Save mrackwitz/e91892f3a22c5e0a797e60f8d7e75127 to your computer and use it in GitHub Desktop.
Dates around DST end
import Foundation
let calendar = Calendar(identifier: .gregorian)
// Daylight Saving Time ends in 2017 on Nov 5th, 2:00 AM in the United States.
// Let's instantiate some `Date`s around that.
let nov4_1am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 4, hour: 1))!
let nov4_2am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 4, hour: 2))!
let nov4_3am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 4, hour: 3))!
let nov5_1am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 5, hour: 1))!
let nov5_2am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 5, hour: 2))!
let nov5_3am = calendar.date(from: DateComponents(year: 2017, month: 11, day: 5, hour: 3))!
// We should always rely on a calendar to get specific dates. Assuming that
// a day always has 86400s (24*60*60) can break, as we can see below.
Date(timeIntervalSince1970: nov4_1am.timeIntervalSince1970 + 86400) // That's expected…
Date(timeIntervalSince1970: nov4_2am.timeIntervalSince1970 + 86400) // … but this?
Date(timeIntervalSince1970: nov5_1am.timeIntervalSince1970 + 3600) // Or this?
// We cannot rely on this assumption for calculating the difference between two dates.
func naiveDaysDifference(from: Date, to: Date) -> Int {
let timestampDifference = to.timeIntervalSince1970 - from.timeIntervalSince1970
return Int((timestampDifference / 86400).rounded(.up))
}
// We can and should use the Foundation classes instead though!
func calendarBasedDaysDifference(from: Date, to: Date) -> Int {
return calendar.dateComponents(Set([Calendar.Component.day]), from: from, to: to).day!
}
// Helper function
func compare(from: Date, to: Date) -> (naive: Int, calendarBased: Int) {
return (naiveDaysDifference(from: from, to: to), calendarBasedDaysDifference(from: from, to: to))
}
compare(from: nov4_1am, to: nov5_1am)
compare(from: nov4_2am, to: nov5_2am) // 2 ≠ 1 ⚡️
compare(from: nov4_3am, to: nov5_3am)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment