Friday, Dec 8, 2023
EEEE, MMM d, yyyy
|
EEEE, MMM d, yyyy |
12/08/2023
MM/dd/yyyy
|
MM/dd/yyyy |
12-08-2023 15:32
MM-dd-yyyy HH:mm
|
MM-dd-yyyy HH:mm |
Dec 8, 3:32 PM
MMM d, h:mm a
|
MMM d, h:mm a |
December 2023
MMMM yyyy
|
MMMM yyyy |
Dec 8, 2023
MMM d, yyyy
|
MMM d, yyyy |
Fri, 8 Dec 2023 15:32:43 +0000
E, d MMM yyyy HH:mm:ss Z
|
E, d MMM yyyy HH:mm:ss Z |
2023-12-08T15:32:43+0000
yyyy-MM-dd'T'HH:mm:ssZ
|
yyyy-MM-dd'T'HH:mm:ssZ |
08.12.23
dd.MM.yy
|
dd.MM.yy |
15:32:43.184
HH:mm:ss.SSS
|
HH:mm:ss.SSS |
The following table’s sample column are mostly based on the time December 14th, 2008 4:35 PM UTC
.
Characters | Example | Description |
---|---|---|
Year | ||
y | 2008 | |
yy | 08 | |
yyyy | 2008 | |
Quarter | ||
Q | 4 | |
QQQ | Q4 | |
QQQQ | 4th quarter | |
Month | ||
M | 12 | |
MM | 12 | |
MMM | Dec | |
MMMM | December | |
MMMMM | D | |
Day | ||
d | 14 | |
dd | 14 | |
F | 2 | |
E | Tue | |
EEEE | Tuesday | |
EEEEE | T | |
EEEEEE | Tu | |
Hour | ||
h | 4 | |
hh | 04 | |
H | 16 | |
HH | 16 | |
a | PM | |
Minute | ||
m | 35 | |
mm | 35 | |
Second | ||
s | 8 | |
ss | 08 | |
SSS | 123 | |
Time Zone | ||
zzz | CST | |
zzzz | Central Standard Time | |
ZZZZ | CST-06:00 | |
Z | -0600 | |
ZZZZZ | -06:00 | |
For the full reference of available format options, see Unicode Technical Reference #35. |
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.
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.
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.
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.
Apple Documentation also has a dedicated section about those cases here.
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).
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, es_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 es_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.
This section was contributed by Olivier Halligon
nsdateformatter.com is written with Swift 5.5, originally as a means to learn open-source Swift, the Swift Package Manager, and deploying to Linux. It uses the Vapor web application framework and is deployed to Heroku.
The site is open source, so if you want to fix a bug or submit an enhancement, feel free to submit a pull request.
Ben is an experienced software developer from Houston, TX. He is the founder of NSScreencast, where you can find over 500 screencasts on iOS development topics.
Want to see how to use DateFormatter in Swift?
Check out this free screencast:
Parsing and Formatting Dates