Format dates the right way in Swift, iOS

How to convert Date into a human readable string? Most iOS apps perform date formatting, but many of them don’t do it properly. Let’s look at a few ways how to convert Date into String in Swift.

If you type “How to format date in Swift?” into Google, the first result is a StackOverflow answer with DateFormatter.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter.string(from: date)

The code above works, but there are two main problems with it - “2021-01-01 00:00:00” isn’t an easily readable date format for humans and it’s not localized into the user’s locale. There are usecases were you want to use fixed dateFormat such as when encoding data for an external API, but you shouldn’t use it for texts you display to the user.

Better way to use DateFormatter would be:

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .medium
return dateFormatter.string(from: date)

When you use the dateStyle and timeStyle, the output is automatically formatted to the phone’s locale (for example “April 13, 2021 at 1:55:30 PM” in US). If you want to omit the date or time part, you can just set its style to .none.

Sometimes you want to display formatted date in relation to another date. A good example is a feed of activity, where “3 minutes ago” looks much better than “April 13, 2021 at 1:55 PM”. Fortunately, since iOS 13 we have the RelativeDateTimeFormatter, so relative date formatting can be done in a few lines of code. It’s recommended to specify formattingContext (beginningOfSentence, middleOfSentence, standalone, …) for proper formatting in all locales.

let formatter = RelativeDateTimeFormatter()
formatter.dateTimeStyle = .named
formatter.formattingContext = .standalone
return formatter.localizedString(for: self, relativeTo: Date())

Let’s say you have a workout with start and end dates. You can use format both dates with DateFormatter , but there is a better way - DateIntervalFormatter allows you to format time interval (two Date values).

let dateFormatter = DateIntervalFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
return dateFormatter.string(from: workoutStart, to: workoutEnd)

DateIntervalFormatter output may look like “April 13, 2021, 6:01 AM – 2:11 PM”. Similarly to the DateFormatter, you can specify desierd length by setting the dateStyle and timeStyle and you don’t have to worry about localizing the format to user’s locale.

Propper date formatting significantly improves the user experience and it is a matter of a few code lines. If you have any feedback or question, feel free to reach out via Twitter.