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

Viewed 704

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!

1 Answers

.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.

Related