swifttime

How to add exactly 1 millisecond to a Swift Date


Working with Swift 5.0 in Xcode 16.4. I have a Date instance and I would like to add exactly 1 millisecond to it.

Date.addingTimeInterval(TimeInterval) and friends appear to be relevant methods. However, I see that TimeInterval is a typealias for Double. That suggests that fractions of a second, aside from multiples of 2 to a negative power, can't be represented exactly. In particular, it appears that 1 millisecond (or any number n if n/1000 is not a multiple of a negative power of 2) cannot be represented exactly.

Do I understand correctly that there is no way to add exactly 1 millisecond to a Date? It's OK if that's the case, I can make it work; I just want to know.


Solution

  • You are correct that Dates are backed by floating point Doubles. From the documentation here,

    The standard unit of time for date objects is floating point value typed as NSTimeInterval and is expressed in seconds. This type makes possible a wide and fine-grained range of date and time values, giving precision within milliseconds for dates 10,000 years apart.

    Granted, this is talking about NSDate, but Swift's Date, introduced by SE-0069, is not really different from it in terms of implementation.

    The overlay is deployed back to the first supported release for Swift, so the implementation of these types will use the existing reference type API.

    See also the implementation of Date in swift-foundation, which is what is used on non-Apple platforms. It is just a wrapper around a TimeInterval.

    This discussion on Swift Forums about changing the representation of Date to an integer type is also relevant. I want to particularly highlight this comment:

    The one thing I'm pretty sure we can't change about Date is its representation in encoded form (usually as a Double, in property lists or keyed archives). Even if we choose to change its underlying representation to be integer based, or Int128 based - we still have to read it in and write it out as a double, which will almost certainly result in the same kind of precision errors described here.