How to decode dates in ISO 8601 format


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


If you write code that interacts with web services, there’s a good chance that you will be faced with dates encoded in a format like this one:

This format is called ISO 8601 and its usage is quite common in web services, because it allows to encode all the information needed to precisely specify a Date.

And indeed, if you look closer you can see that the String contains the day, month, year, hour, minute, second and even the timezone:

Now the question is: how can you decode this format into an actual Date?

You might be tempted to create a DateFormatter and configure it with a dateFormat that matches the structure of the String:

But while this would work fine, there’s actually no need to manually configure a formatter.

Because the ISO 8601 format is very popular, Apple introduced back in iOS 10 a built-in formatter specifically made to handle this format.

So you can just create an instance of ISO8601DateFormatter and it will be able to decode the Date out-of-the-box:

Even better, if the Date you need to decode has been encoded in a slightly different way, this formatter comes with an API that allows you to easily handle that situation:

Of course, most of the time you won’t be decoding a Date by itself, but rather a Date that is part of a larger piece of data:

Fortunately, this use case is also very easy to handle: after you’ve created your JSONDecoder, you only need to set its .dateDecodingStrategy property to the value .iso8601 and the Date will be properly decoded.

That’s all for this article, I hope that you’ve enjoyed learning about this very useful formatter!

Here’s the code if you want to experiment with it:

import Foundation

// With a classic DateFormatter

let encodedDate = "2024-04-07T14:22:40Z"

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

let decodedDate = formatter.date(from: encodedDate)

// With an ISO8601DateFormatter

let encodedDate = "2024-04-07T14:22:40Z"

let iso8601formatter = ISO8601DateFormatter()

let decodedDate = iso8601formatter.date(from: encodedDate)

// With a customized ISO8601DateFormatter

let encodedDate = "20240407T142240Z"

let iso8601formatter = ISO8601DateFormatter()

iso8601formatter.formatOptions = [
    .withDay,
    .withMonth,
    .withYear,
    .withTime,
    .withTimeZone,
]

let decodedDate = iso8601formatter.date(from: encodedDate)

// With a JSONDecoder

struct Time: Decodable {
    let date: Date
}

let json = """
{
  "date": "2024-04-07T14:22:40Z"
}
"""

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

let decoded = try decoder.decode(Time.self, from: json.data(using: .utf8)!)
Previous
Previous

Did you know that a few popular iOS apps are open-source? 🤨

Next
Next

How to refactor code with regular expressions 🤯