I noticed that when comparing two instances of a Swift Date
with ==
, they qualify as the same date when the difference in DateComponents.nanoseconds
is less than 30. For example:
let calendar = Calendar(identifier: .gregorian)
let startComps = DateComponents(year: 2017, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)
let endComps = DateComponents(year: 2017, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 29)
let startDate = calendar.date(from: startComps)!
let endDate = calendar.date(from: endComps)!
print(startDate == endDate)
//prints true, changing 29 to 30 prints false
The behavior is the same if comparing with startDate.compare(endDate) == .orderedSame
. I couldn't find any mention of this in the docs or headers. Is there a logical reason for 30 nanoseconds to be the cutoff for equality?
Dates are represented internally as a Double
. Double
s have a limited precision. Your first date there has an internal value of 504950400.000000000000000
(when printed at 15 decimal places). The next higher representable value is 504950400.000000059604645
. It just so happens that your end date, if you set the nanoseconds to 30
, is 504950400.000000059604645
(which actually corresponds to a nanoseconds value of 59
).
Which is to say, in January of 2017, Date
can only distinguish between 59-nanosecond intervals. Meanwhile back in January of 2001, Date
can distinguish every single nanosecond. And in 2027 it will distinguish between 119-nanosecond intervals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With