Categories
Programming

Dates and times in Swift 5, part 2: Formatting and parsing dates and times

clock and calendar

Dates and times in Swift 5In the previous article in this series on working with dates and times in Swift 5, we looked at three key structs for date and time programming in Swift:

  • Date represents a single point in time, using a format that can easily be translated into just about any calendar and time-reckoning system: a number of seconds relative to the start of the Third Millennium (January 1, 2001, 00:00:00 UTC).
  • DateComponents specifies time units like year, month, day, hour, minute, and more to represent either a point in time or a duration of time.
  • Calendar provides a context for Dates, and converts Dates to DateComponents and DateComponents to Dates.

These structs all deal with the internal representation of dates and times in Swift 5.

In this article, we’ll look at the DateFormatter class, which allows us to deal with the  external representation of dates and times in Swift 5 as strings to be presented to the user. We use this class to convert Dates into formatted Strings that match the user’s language and locale, and properly-formatted Strings into Dates.

Tap the image to see it at full size.

We’ve already used the Date struct’s description property and description(with:) method to print its value in a human-readable form, but they’re meant for debugging purposes only, and not for presenting date and time information to the user. When presenting dates to the user in string form, use strings that have been created by DateFormatter.

Let’s convert a Date into a String, part 1: Just the date

Start a new playground and enter the following code, which gives us a Date that we can format — June 2, 2014, the day when the Swift programming language was first released:

This code is similar to code we entered in the previous article:

  1. Get the user’s current Calendar.
  2. Create a DateComponents struct, swiftDebutDateComponents, providing the year:month:, and day: parameters that correspond to the date June 2, 2014.
  3. Use the user’s Calendar to create swiftDebutDate using swiftDebutDateComponents.

Let’s try turning this date into a string with a DateFormatter.

Add the following to the playground, then run it:

The output should look like this:

Swift’s debut date, via the DateFormatter:

You may be surprised that the result is an empty String. That’s because you need to specify a dateStyle, which specifies which pre-defined format should be used for the date. We’ll start with the short style.

Add the following to the playground, then run it:

The output should look like this:

Swift’s debut date, “short” style: 6/2/14.

Let’s try the other styles: medium, long, full, and none.

Add the following to the playground, then run it:

The output should look like this:

Swift’s debut date, “medium” style: Jun 2, 2014.
Swift’s debut date, “long” style: June 2, 2014.
Swift’s debut date, “full” style: Monday, June 2, 2014.
Swift’s debut date, “none” style: .

If turns out that the default dateStyle is none. Why would there be a dateStyle called .none? I’ll explain in the next section.

Let’s convert a Date into a String, part 2: A date and a time

Let’s create a date and approximate known time: When SwiftUI was announced at WWDC 2019. It’s introduced 2 hours and 8 minutes into a keynote that started at 10:00 a.m. Pacific Daylight Time, so we’ll say it debuted at 12:08 p.m. PDT on June 3, 2019.

Add the following to the playground, then run it:

On my computer, the output looked like this:

The newly-created date: Monday, June 3, 2019 at 3:08:00 PM Eastern Daylight Time.

The date and time you’ll see will be determined your system calendar settings.

Now that we have a date and time, let’s format it using the dateStyle property to style the date part, and timeStyle property to style the time part.

Add the following to the playground, then run it:

On my computer, the output looked like this:

Swift’s debut date and time, “short” style: 6/3/19, 3:08 PM.
Swift’s debut date and time, “medium” style: Jun 3, 2019 at 3:08:00 PM.
Swift’s debut date and time, “long” style: June 3, 2019 at 3:08:00 PM EDT.
Swift’s debut date and time, “full” style: Monday, June 3, 2019 at 3:08:00 PM Eastern Daylight Time.

You can mix and match dateStyle and timeStyle settings. Add the following to the playground, then run it:

On my computer, the output looked like this:

Swift’s debut date and time, with “full” style date and “short” style time: Monday, June 3, 2019 at 3:08 PM.

Now that we’re working with a date and time, I can tell you what the .none style is for: for suppressing the display of the date or time in a formatted date string.

Add the following to the playground, then run it:

Remember that the Date struct represents a single point in time, which has both a date and a time. The .none style for DateFormatter‘s dateStyle and timeStyle properties allows us to create a String representation of a Date that shows only its date or time part.

This table summarizes the different dateStyle and timeStyle settings for the US English language setting:

Setting dateStyle timeStyle
.none [ empty string ] [ empty string ]
.short 6/3/19 3:08 PM
.medium Jun 3, 2019 3:08:00 PM
.long June 3, 2019 3:08:00 PM EDT
.full Monday, June 3, 2019 3:08:00 PM Eastern Daylight Time

Let’s convert a Date into a String, part 3: Displaying dates and times in other languages

DateFormatter defaults to the user’s preferred language, as specified in their settings. In my case, that’s US English. By setting the locale property of the DateFormatter, I can specify the language for my formatted date strings. Add the following to the playground, then run it:

On my computer, the output looked like this:

International French: lundi 3 juin 2019 à 15:08:00 heure d’été de l’Est.
Canadian French: lundi 3 juin 2019 à 15:08:00 heure avancée de l’Est.
Croatian: ponedjeljak, 3. lipnja 2019. u 15:08:00 (istočno ljetno vrijeme).
Korean: 2019 6 3 월요일 오후 3 8 0 동부 하계 표준시.

Let’s convert a Date into a String, part 4: Custom date/time formats

In addition to the built-in formats for dates, you can tell DateFormatter to use a custom format.

Before we begin working with custom date/time formats, I should point out that if you need to display a Date as a String to the user, it’s best if you use Swift’s built-in dateStyle and timeStyle values. They display dates and times properly, according to the user’s settings, which include country and language. You’d be surprised how date formats differ from culture to culture, and it’s better to let Swift do the formatting work.

However, there are times when you need to format dates and times in a specific way that doesn’t match the styles provided by DateFormatter’s dateStyle and timeStyle properties, such as when dealing with certain APIs. That’s where DateFormatter’s dateFormat property comes in handy.

To be certain that the DateFormatter will use your custom date format, set its locale property to POSIX, then define the custom date format string in dateFormat.

Add the following to the playground, then run it:

You can use the date format specifiers listed in Appendix F of the Unicode Technical Standard #35 to define the formatting String for the dateFormat property. Here are some examples (Add the following to the playground, then run it):

Let’s convert a String into a Date

DateFormatter works the other way — just as it can convert Dates to Strings, it can also convert Strings to Dates. By setting its dateFormat to the format of the String it should expect, you can use its date(from:) method to convert a String into a Date.

Once again, use the date format specifiers listed in Appendix F of the Unicode Technical Standard #35 to define the formatting String for the dateFormat property.

Add the following to the playground, then run it:

On my computer, the output looked like this:

newDate1’s value is: 2019-06-03 07:08:00 +0000.
newDate2’s value is: nil.

Let’s change the dateFormat string and try it again. Add the following to the playground, then run it:

On my computer, the output looked like this:

newDate3’s value is: nil.
newDate4’s value is: 2019-06-06 19:08:00 +0000.

If you’re trying to parse a weird date format, use a weird date format string. Add the following to the playground, then run it:

On my computer, the output looked like this:

weirdEmojiDate’s value is: 2020-11-28 05:00:00 +0000.

Wrapping it all up

Here’s the complete code for the playground containing all the code we just worked with:

You can download the playground here (3KB, zipped Xcode playground file).

In the next installment on dates and times in Swift 5, we’ll look at date calculations.

The How to work with dates and times in Swift 5 series

Dates and times in Swift 5Here are the articles in this series:

3 replies on “Dates and times in Swift 5, part 2: Formatting and parsing dates and times”

Leave a Reply

Your email address will not be published. Required fields are marked *