The following table’s sample column are mostly based on the time December 14th, 2008 4:35 PM UTC .

The main fallacy to be aware of: dateFormat is not locale-aware

You should be aware that using a custom dateFormat comes with a risk of falling into some fallacies.

Especially, you need to realize that the user can use different Locales , and that date formats are different for different locales, regions and user settings. For example one date formatted with a dateFormat that fits the US might become confusing for anyone in Europe.

The TL;DR

Use dateStyle and timeStyle over dateFormat whenever you can. Explain the date fallacies to your designer if you need to.

and over whenever you can. Explain the date fallacies to your designer if you need to. If you can't find a fitting dateStyle/timeStyle to format your UI dates, then at least use dateFormatter.setLocalizedDateFormatFromTemplate(…) to account for the user's locale.

to format your UI dates, then at least use to account for the user's locale. When parsing ISO8601 internet dates, always use ISO8601DateFormatter

If you can't because your API format doesn't fit ISO8601 and you still absolutely need to use a custom dateFormat , then be sure to also set your dateFormatter.locale to the special value Locale(identifier: "en_US_POSIX") .

Formatting user-visible dates for your UI

Apple already has a dedicated paragraph in their documentation about best practices for formatting a date to present to the user in a locale-aware way. Below is just the TL;DR.

Using dateStyle and timeStyle

The main recommendation to follow is to prefer using dateStyle and timeStyle over dateFormat .

This is because those are locale-aware and account for a lot of edge cases that you can otherwise miss when using a custom and hardcoded dateFormat .

I would even advise you to convince your designer against using a custom format and explain them that Date and Time is a tricky subject with lots of edge cases and that it's generally not worth using a custom format that might fit their assumptions about the locale and region they're used to use but might not fit a lot of other's.

Using DateFormatter's templating methods to auto-adjust for the user's Locale

If you still need to use a custom dateFormat , be sure that you use dateFormatter.setLocalizedDateFormatFromTemplate(…) or dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate:…options:…locale:…) instead of setting it to a hard-coded String .

Working with ISO8601 dates and fixed formats for APIs

Apple Documentation also has a dedicated section about those cases here.

Using ISO8601DateFormatter

If you need to parse ISO8601 dates, consider using ISODateFormatter instead of a DateFormatter with a custom dateFormat .

This class is dedicated to handle the ISO8601 standard and all its possible variants and edge cases better than using a custom dateFormat would.

Tip: One of the little-known options of ISO8601DateFormatter is that it is also able to handle fractional seconds if you set it up using formatter.formatOptions.insert(.withFractionalSeconds) .

Always use the en_US_POSIX locale for fixed formats

In last resort, if you need to parse a date for an API that doesn’t fall into ISO8601 format, but that also isn’t intended for UI (and should thus not depend on the user’s locale/region/language), then that is the only case when you can use a fixed string as a value for dateFormatter.dateFormat .

BUT then ALWAYS also set your dateFormatter.locale to Locale(identifier: "en_US_POSIX") on your DateFormatter .

en_US_POSIX is a special locale that guarantees that the formatting and parsing won’t depend on the phone’s locale, and is designed exactly for parsing those “internet dates with fixed format”.

If you don't force the locale to en_US_POSIX , there are risks that your code might seem to work in some regions (like the US), but will fail to parse your API responses if the user has its phone set in another region (e.g. en_GB , en_ES or fr_FR ), where date formatting is different, or use 12-hour time and not 24-hour time.

You can test this kind of edge case on device by setting your phone settings to use en_ES for example and set it to use 12-hour with am/pm, and try to parse a date like 2020-01-15T22:00:00Z .

For more information about those commonly overlooked cases, you can read Apple's TN1480.