-3

I have strings like this 2020-09-21T21:13:55.636Z... I want to convert them into Dates and here's what I do;

func convertToDate(str: String) -> Date {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

    return dateFormatter.date(from: str)!
}

The above code crashes on the unwrapping. I'm guessing it's because of the format... Any idea what I'm doing wrong?

Sotiris Kaniras
  • 520
  • 1
  • 12
  • 30
  • 1
    Include the milliseconds in the format "yyyy-MM-dd'T'HH:mm:ss.SSSZ" – Joakim Danielson Sep 21 '20 at 21:30
  • @JoakimDanielson I love you! Post it as an answer so I can accept it! – Sotiris Kaniras Sep 21 '20 at 21:32
  • 1
    Be aware that your app will crash if `str` can't be converted to a date – Claudio Sep 21 '20 at 21:40
  • Here is an old answer from @JoakimDanielson [here](https://stackoverflow.com/a/50809888/13426627) – 0-1 Sep 21 '20 at 21:49
  • 2
    Note that this will create a new dateFormatter every time you call this property and it might fail if the user device 24hour is set to 12. You need to set the locale to "en_US_POSIX" before setting the dateFormat when parsing a fixed date format. – Leo Dabus Sep 21 '20 at 21:50

1 Answers1

2

For that date string you should use ISO8601DateFormatter, like this:

var str = "2020-09-21T21:13:55.636Z"

let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = formatter.date(from: str)

That will save you the trouble of trying to get a format string exactly right.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • 1
    This is wrong. You need to use `.withInternetDateTime` as well as `.withFractionalSeconds`. This would result in `"Dec 31, 1999 at 10:00 PM"` `[.withInternetDateTime, .withFractionalSeconds]` or simply insert the fractional seconds to the default options `formatter.formatOptions.insert(.withFractionalSeconds)` – Leo Dabus Sep 21 '20 at 21:52
  • 1
    @LeoDabus Fixed, thank you – Tom Harrington Sep 21 '20 at 22:57