During WWDC 2021, Apple introduced the new APIs that make date formatting a lot easier. Before iOS 15, we had to create a DateFormatter and later use it to convert a Date into a String:
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateStyle = .medium
formatter.timeStyle = .medium
return formatter
}()
let now = Date.now
let dateString = dateFormatter.string(from: now)
// Oct 21, 2020 at 7:48 AMFrom iOS 15, we can condense the code above to just two lines:
let now = Date.now
let dateString = now.formatted()
// 10/21/2020, 7:48 AMBy default, the formatted() method will use a sensible default format. What's cool is that it will respect the user's preferences. For example, for October 21st, 2020 at 07:48 in the US region, we will get 10/21/2020, 7:48 AM, but in Poland, we will have 21/10/2020 07:48.
Of course, we can adjust the formatting to our needs by customizing the date and time styles separately:
let now = Date.now
let dateString = now.formatted(date: .long, time: .standard)
// October 21, 2020, 7:48:43 AMAnd we can also completely omit the part we don't need:
let onlyDate = now.formatted(date: .numeric, time: .omitted)
// 10/21/2020
let onlyTime = now.formatted(date: .omitted, time: .shortened)
// 7:48 AMHere is the list of currently available DateStyles:
| Name | Example |
|---|---|
| omited | |
| numeric | 10/21/2020 |
| abbreviated | Oct 21, 2010 |
| long | October 21, 2020 |
| complete | Wednesday, October 21, 2020 |
And TimeStyles:
| Name | Example |
|---|---|
| omited | |
| shortened |
04:29 PM or 16:29 |
| standard |
4:29:24 PM or 16:29:24 |
| complete |
4:29:24 PM PDT or 16:29:24 GMT |
If the built-in styles are not suitable, we can define a custom format:
let now = Date.now
let dateString = now.formatted(.dateTime.year().month(.wide).day(.twoDigits).weekday().hour(.twoDigitsNoAMPM).minute(.defaultDigits))
// Wed, October 21, 2020, 07:48Using this method, we can select and customize the date or time components we need. The order of components does not matter as the formatted() method will adjust the output to the user's locale. Beside the .dateTime style, Apple also provided the .iso8601 style:
let now = Date.now
let dateString = now.formatted(.iso8601)
// 20201021T074843Z
let dateString = now.formatted(.iso8601.year().month().day().dateSeparator(.dash).dateTimeSeparator(.space).time(includingFractionalSeconds: false) .timeSeparator(.colon))
// 2020-10-21 07:48:43If we need our custom style, we can do this by creating a formatter that conforms to the FormatStyle protocol:
struct BrackedDateTimeStyle: FormatStyle {
typealias FormatInput = Date
typealias FormatOutput = String
func format(_ value: Self.FormatInput) -> Self.FormatOutput {
return "[\(value)]"
}
}
let now = Date.now
let dateString = now.formatted(BrackedDateTimeStyle())
// [2020-10-21 07:48:43 +0000]We can also add an extension to the FormatStyle to make usage of our custom format more similar to Apple's API:
extension FormatStyle where Self == BrackedDateTimeStyle {
static var brackedDateTime: BrackedDateTimeStyle {
BrackedDateTimeStyle()
}
}
let now = Date.now
let dateString = now.formatted(.brackedDateTime)That's it. The new Date formatting APIs will not replace the good old DateFormatter. But in most cases, it's going to make our life easier.
If you want to know how to convert a String into a Date, check out my other article:


Comments
Anything interesting to share? Write a comment.