iphaaw
iphaaw

Reputation: 7204

Swift: DateFormatter returning nil

I'm having a strange problem with DateFormatter returning nil for a valid data string.

Here is my code:

func dateFromString(_ dateString:String,  format: String = "dd/MM/yy") -> Date?
{
    let dueDateFormatter = DateFormatter()
    dueDateFormatter.timeZone = TimeZone(identifier: "UTC")!
    dueDateFormatter.dateFormat = format
    let date = dueDateFormatter.date(from: dateString)
    return date
 }

func applicationDidFinishLaunching(_ aNotification: Notification)
{
    print("Launched")
    let dd = dateFromString("Aug 20", format: "MMM yy")
    print (dd!)
}

In the debugger:

enter image description here

It seems that the variable is set and can be used within the application, but the debugger is not showing it. Is this an Xcode bug or am I going mad?

Everything works fine in the playground and I have used this function many other times in other areas of my code.

I'm using 10.15.4 and Xcode 11.4.1

Upvotes: 1

Views: 469

Answers (1)

Sweeper
Sweeper

Reputation: 270980

After a bit of playing with the debugger, I figured out why this is.

The reason why this happens is because it's Date. If you change your method to return an NSDate, the debugger shows it correctly.

From what I observed: This behaviour happens for the group of types that Date, and others such as TimeZone belong to. That is, Swift types in Foundation that have an Objective-C counterpart, but isn't a "direct port" like DateFormatter/NSDateFormatter. I can't really describe it well, but it's basically the types in Foundation where their documentation page doesn't let you select an Objective-C version on the top right. This happens for most of the types on this page that are also in Foundation. Exceptions are:

  • AffineTransform
  • Data
  • DateInterval
  • Measurement
  • Notification

If you use another debugger command, po, you'll see that it displays Dates correctly. So what's the difference between print and po?

Running help print and help po can tell us that:

print:

    Evaluate an expression on the current thread.  Displays any returned value
    with LLDB's default formatting.  Expects 'raw' input (see 'help
    raw-input'.)

    Syntax: print <expr>

    Command Options Usage:
      print <expr>


    'print' is an abbreviation for 'expression --'

po:

    Evaluate an expression on the current thread.  Displays any returned value
    with formatting controlled by the type's author.  Expects 'raw' input (see
    'help raw-input'.)

    Syntax: po <expr>

    Command Options Usage:
      po <expr>

    'po' is an abbreviation for 'expression -O  --'

Notice how for po it says "with formatting controlled by the type's author". And if you type help expression, you will see what the -O option for expression does:

Display using a language-specific description API, if possible.

So it is possible to conclude that po is more "specific to Swift" than print, hence it is able to print out things like Date and TimeZones, because print simply doesn't know how to print a Swift Date.

Upvotes: 2

Related Questions