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)!)