swiftfoundation

What is the difference between Date.addingTimeInterval(_:) and Date.advanced(by:)?


Foundation's Date struct provides both Date.addingTimeInterval(_:) and Date.advanced(by:) which appear to be functionally identical, but are obviously separate methods. Is there actually a difference between them or are they ultimately the same?

Looking at the documentation, advanced(by:) is missing anything at all, and addingTimeInterval(_:) only says

The value to add, in seconds.

When comparing to NSDate, advanced(by:) is missing entirely. The plot thickens!


Solution

  • .addingTimeInterval(_:) is a long-existing method, coming from ObjC NSDate. .advanced(by:) exists to match Strideable conformance in Swift. Date similarly has a Stride typealias.

    That said, Date does not actually conform to Strideable, and this has been discussed and generally rejected.

    The Strideable pseudo-conformance seems to have been added as part of a large merge from Xcode 11.4 in an extension called Schedulers+Date that appears to be part of Combine (which is not open source). I don't see any discussion of it in the forums, except for a note that it broke existing code. The change notes:

    // Date cannot conform to Strideable per rdar://35158274
    @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
     extension Date /* : Strideable */ {
    

    My hunch is that somewhere inside of Combine, there's a retroactive conformance of Date to Strideable. You can get the same by just asking for it:

    extension Date: Strideable {}
    

    It feels like the Swift stdlib team accepted that Date should not be Strideable (and I agree with the reasoning, because it invites a lot of common date bugs), but some other team in Apple wanted it and put the hooks into stdlib anyway, without putting in the conformance.