ISO8601DateFormatter fails to parse a valid ISO-8601 date

(Mohsen) #1

Although, 2017-09-04T04:14:37.000Z is a valid ISO8601-formatted date, ISO8601DateFormatter cannot parse it. Seemingly, it happens when the string that represents an ISO8601-formatted date contains fractions of a second:

let formatter = ISO8601DateFormatter()

let ret1 = "2017-09-04T04:14:37.000Z"); // ret1 is null
let ret2 = "2017-09-04T04:14:37Z"); // ret2 is not null

I tracked down the issue and found that under the hood withInternetDateTime is used for formatOption and according to the documentation it doesn't support seconds fractions.

fileprivate var _iso8601Formatter: ISO8601DateFormatter = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = .withInternetDateTime
    return formatter

Useful links:

ISO8601DateFormatter source code
NSDateFormatter milliseconds bug

(Thomas Krajacic) #2

There is another option .withFractionalSeconds which allows parsing when fractional seconds are included. (use [.withInternetDateTime, .withFractionalSeconds])

That being said, it is then not parsing the one without fractional seconds :frowning:

(Mohsen) #3

True. As far as I know, the fractional seconds part must be optional.

(Srđan Rašić) #4

I have experienced the same issue. ISO8601DateFormatter does not support full ISO08601 with regard to fractional seconds. The way I've worked around it is by using a .custom .dateDecodingStrategy on JSONDecoder that attempts to parse the date through a chain of formatters.

(Thomas Krajacic) #5

That is a very inefficient way of doing this I guess.
If you know at least that certain properties have certain formats, you can use a custom strategy and switch on the current key.

(Mohsen) #6

This is what I do too. I created this post to bring up the issue to see if there is any reasonable explanation for not supporting seconds fractions or not. Otherwise, we should fix it.

1 Like
(Srđan Rašić) #7

I don't think I could assume that certain properties would have guaranteed format. After all, they were all ISO08601, it just that sometimes fractional seconds were missing.

But I agree, switch would be more efficient if possible.