Search code examples
swiftdateread-eval-print-loop

Swift date(byAdding:to:) returns nil for trivial calculation in REPL


I expect this to return a Date object representing the time one hour from now:

Calendar.current.date(byAdding: DateComponents(hour: 1), to: Date()) 

However it returns nil. This seems like a rather straightforward use of the API so perhaps I have some fundamental misconception about how this API should work?

This only appears to affect the swift command line REPL included with Xcode (version 11.3.1 on macOS Catalina 10.15.3).

Interestingly, wrapping the above code in a print() call forces it to print the correct result. So why is it showing nil?

Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)
Target: x86_64-apple-darwin19.3.0

Solution

  • This is a bug in the Swift REPL, see

    It affects both optional and non-optional values of some Swift overlay types (such as Date, Calendar, URL). Example:

    $ swift
    Welcome to Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15).
    Type :help for assistance.
      1> import Foundation
      2>  
      3> let d1 = Date()
    d1: Date = {}
      4> let d2: Date? = Date()
    d2: Date? = nil
      5> let url = URL(string: "https://www.google.com")
    url: URL? = nil
    

    As a workaround you can print the values:

      7> print(d1)
    2020-03-03 10:17:00 +0000
      8> print(d2)
    Optional(2020-03-03 10:17:07 +0000)
      9> print(url)
    Optional(https://www.google.com)