In Bite #287, we built a small extension to Date to allow us to format relative date strings like "10 minutes ago". We used a bunch of if statements and built our final String . This was a nice way to learn about working with DateComponents , but it turns out 🛎 Foundation actually provides a class to do something similar, and it's much more powerful.

Today we'll continue our look at Foundation's date and time-related functionality with DateComponentsFormatter . Let's dive in.

Much like its cousin DateFormatter (Bite #286), DateComponentsFormatter is all about converting a TimeInterval or DateComponents into a nicely formatted, human-readable String . (Note: It doesn't support parsing Strings yet. Conversions are a one way trip for now).

We'll start with a new formatter:

let formatter = DateComponentsFormatter ()

Then we'll configure a few options:

formatter . unitsStyle = . full formatter . allowedUnits = [ . minute , . second ]

And finally, we'll ask for a String describing an example TimeInterval :

formatter . string ( from : 543.0 ) // "9 minutes, 3 seconds"

Like many Foundation types, DateComponentsFormatter is a super customizable powerhouse. Let's try a few more options:

formatter . unitsStyle = . abbreviated formatter . string ( from : 123.0 ) // "2m 3s"

formatter . unitsStyle = . short formatter . string ( from : 123.0 ) // "2 min, 3 sec"

formatter . unitsStyle = . spellOut formatter . string ( from : 123.0 ) // "two minutes, three seconds"

formatter . includesApproximationPhrase = true formatter . includesTimeRemainingPhrase = true formatter . unitsStyle = . brief formatter . string ( from : 123.0 ) // "About 2min 3sec remaining"

Neat. Fun Fact: If you've ever seen a progress bar or "time remaining" bar in iOS or macOS, you've seen a DateComponentsFormatter in action.

We've only been allowing .minutes and .seconds . Let's try allowing some different sets of units:

let formatter = DateComponentsFormatter () formatter . unitsStyle = . full formatter . allowedUnits = [ . minute , . second ] formatter . string ( from : 1234567.0 ) // "20,576 minutes, 7 seconds"

formatter . allowedUnits = [ . day , . hour , . minute , . second ] formatter . string ( from : 1234567.0 ) // "14 days, 6 hours, 56 minutes, 7 seconds"

formatter . allowedUnits = [ . day , . minute , . second ] formatter . string ( from : 1234567.0 ) // "14 days, 416 minutes, 7 seconds"

Neat!