An extensive guide to formatting dates in Swift
source link: https://www.tuicool.com/articles/7zQZjmY
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
iOS and macOS contain built in support for various ways to format dates, such as for human readable text and to show intervals between dates.
At WWDC19, Apple added a new RelativeDateTimeFormatter
, which formats relative dates from the current date, for example by formatting a past date as “X days ago” or today as “today”.
This guide explores how to display and format dates using many of the different date formatters built into Apple’s platforms.
Setup
As all of the built in date formatters are available in Apple’s Foundation framework, no installation is required to use them. However, make sure to add import Foundation
to the top of your file to be able to use them in your code.
If you’d like to follow along with this guide, just create a Swift Playground using Xcode or the Swift Playgrounds app for iPad.
Additionally, you can click any of the class or header names to go to Apple’s official Developer Documentation.
Formatting Basic Dates
Formatting basic dates is easy with
DateFormatter
. It supports many different time and date styles, allowing you to get the format that you want.
Just create a formatter and set its time and date style to use it:
let formatter = DateFormatter() formatter.timeStyle = .short formatter.dateStyle = .short let currentDate = Date() formatter.string(from: currentDate) // 21/7/2019, 9:41 AM
DateFormatter
can be used with either a date or time style, or both.
Date Styles
None
The .none
style ignores the date and only uses the time style.
formatter.dateStyle = .none formatter.string(from: currentDate)
Short
The .short
style only uses numbers without text.
formatter.dateStyle = .short formatter.string(from: currentDate) // 21/7/2019
Medium
The .medium
style is more human readable and uses the short name of the month.
formatter.dateStyle = .medium formatter.string(from: currentDate) // 21 Jul 2019
Long
The .long
style is the same as the medium style but slightly longer, using the full name of the month.
formatter.dateStyle = .long formatter.string(from: currentDate) // 21 July 2019
Full
The .full
style displays the entire date, including the name of the week.
formatter.dateStyle = .full formatter.string(from: currentDate) // Sunday, 21 July 2019
Time Styles
None
The .none
style ignores the time and only uses the date style.
formatter.timeStyle = .none formatter.string(from: currentDate)
Short
The .short
style is the simplest time style and just shows the hours, minutes, and whether it is currently AM or PM.
formatter.timeStyle = .short formatter.string(from: currentDate) // 9:41 AM
Medium
The .medium
style is the same as the short style but also displays seconds.
formatter.timeStyle = .medium formatter.string(from: currentDate) // 9:41:00 AM
Long
The .long
style is the same as the short style but also displays the time zone.
formatter.timeStyle = .long formatter.string(from: currentDate) // 9:41:00 AM GMT+2
Full
The .full
style displays everything from the other time styles as well as the entire name of the time zone.
formatter.timeStyle = .full formatter.string(from: currentDate) // 9:41:00 AM Central European Summer Time
Formatting DateComponents
DateComponentsFormatter
formats
DateComponents
instances, which contain dates and times specified in terms of units.
Just create a formatter and pass an instance of DateComponents
, and the formatter will represent the components the best it can.
let formatter = DateComponentsFormatter() let components = DateComponents(hour: 9, minute: 41) formatter.string(from: components) // 9:41
Unit Styles
DateComponentsFormatter
contains five unit styles, which format the date components in different ways.
formatter.unitsStyle = .positional // .positional, .abbreviated, .short, .full or .spellOut
Positional
The .positional
style is the default style, and uses typical date position formatting instead of separating each component like the abbreviated style.
formatter.unitsStyle = .positional formatter.string(from: components) // 9:41
Abbreviated
The .abbreviated
style is the shortest style apart from the positional style and abbreviates the components as much as possible.
formatter.unitsStyle = .abbreviated formatter.string(from: components) // 9h 41m
Short
The .short
style uses slightly longer versions of each date component.
formatter.unitsStyle = .short formatter.string(from: components) // 9hr 41min
Full
The .full
style uses the full name for each date component.
formatter.unitsStyle = .full formatter.string(from: components) // 9 hours, 41 minutes
Spelled Out
The .spellOut
style is the longest style and uses spelled out versions of everything.
formatter.unitsStyle = .spellOut formatter.string(from: components) // Nine hours, forty-one minutes
Formatting Date Intervals
DateIntervalFormatter
is similar to the basic DateFormatter
, but it displays both a beginning and end date, such as 21-26 July 2019
.
To use it, create a formatter and generate a string from two dates:
let formatter = DateIntervalFormatter() let currentDate = Date() let twoMinutesAgo = Calendar.current.date(byAdding: .minute, value: -2, to: currentDate) ?? currentDate formatter.string(from: currentDate, to: twoMinutesAgo) // 21/7/2019, 9:41-9:43 AM let fiveDaysAway = Calendar.current.date(byAdding: .day, value: 5, to: currentDate) ?? currentDate formatter.string(from: currentDate, to: fiveDaysAway) // 21/7/2019, 9:41 AM - 26/7/2019, 9:43 AM
Note that by default, the output will be based on the locale and time style from the device preferences, so you might see something different.
Date Styles
DateIntervalFormatter
uses the same date styles that the basic date formatter does. Here are examples of each style:
formatter.dateStyle = .none formatter.string(from: currentDate, to: fiveDaysAway) formatter.dateStyle = .short formatter.string(from: currentDate, to: fiveDaysAway) // 21/7/2019-26/7/2019 formatter.dateStyle = .medium formatter.string(from: currentDate, to: fiveDaysAway) // 21-26 Jul 2019 formatter.dateStyle = .long formatter.string(from: currentDate, to: fiveDaysAway) // 21-26 July 2019 formatter.dateStyle = .full formatter.string(from: currentDate, to: fiveDaysAway) // Sunday, 21-Friday, 26 July 2019
Time Styles
DateIntervalFormatter
uses the same time styles that the basic date formatter does. Here are examples of each style:
formatter.timeStyle = .none formatter.string(from: currentDate, to: twoMinutesAgo) formatter.timeStyle = .short formatter.string(from: currentDate, to: twoMinutesAgo) // 11:00-11:02 AM formatter.timeStyle = .medium formatter.string(from: currentDate, to: twoMinutesAgo) // 11:00:00 AM-11:02:00 AM formatter.timeStyle = .long formatter.string(from: currentDate, to: twoMinutesAgo) // 11:00:00 AM GMT+2-11:02:00 AM GMT+2 formatter.timeStyle = .full formatter.string(from: currentDate, to: twoMinutesAgo) // 11:00:00 AM Central European Summer Time-11:02:00 AM Central European Summer Time
Formatting Relative Dates
Note: RelativeDateTimeFormatter
requires Xcode 11 and the latest beta versions of macOS 10.15 or iOS 13, which are currently in beta, as it is not available on previous versions.
RelativeDateTimeFormatter
is a new date formatter from WWDC19 that formats relative dates as the amount of time between two dates or according to the current date and time.
To use it, create a formatter and generate a string from two dates.
RelativeDateTimeFormatter
supports different date/time and unit styles, which we’ll go through later on.
let formatter = RelativeDateTimeFormatter() formatter.dateTimeStyle = .named formatter.unitsStyle = .full let currentDate = Date() formatter.localizedString(for: currentDate, relativeTo: currentDate) // now let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: currentDate) ?? currentDate formatter.localizedString(for: yesterday, relativeTo: currentDate) // yesterday let fiveDays = Calendar.current.date(byAdding: .day, value: 5, to: currentDate) ?? currentDate formatter.localizedString(for: fiveDays, relativeTo: currentDate) // in 5 days
You can also use a instance of DateComponents
, which will format it based on the current date.
let minusOneDay = DateComponents(day: -1) formatter.localizedString(from: minusOneDay) // yesterday let plusOneDay = DateComponents(day: 1) formatter.localizedString(from: plusOneDay) // tomorrow
As a bonus, all the strings that are generated are already localized, so you don’t need to worry about localization.
Date/Time Styles
RelativeDateTimeFormatter
supports two different date/time styles, which can be used by setting them before generating the string.
formatter.dateTimeStyle = .numeric // .numeric or .named
Numeric
The .numeric
style is the default style and always uses the literal definition of the date.
formatter.dateTimeStyle = .numeric formatter.localizedString(for: currentDate, relativeTo: currentDate) // in 0 seconds formatter.localizedString(for: yesterday, relativeTo: currentDate) // 1 day ago formatter.localizedString(for: fiveDays, relativeTo: currentDate) // in 5 days
Named
The .named
style falls back to the numeric style, but when possible, uses relative names such as yesterday
or tomorrow
.
formatter.dateTimeStyle = .named formatter.localizedString(for: currentDate, relativeTo: currentDate) // now formatter.localizedString(for: yesterday, relativeTo: currentDate) // yesterday formatter.localizedString(for: fiveDays, relativeTo: currentDate) // in 5 days
Unit Styles
RelativeDateTimeFormatter
contains four different unit styles, which format the date in different ways.
formatter.unitsStyle = .full // .abbreviated, .short, .full or .spellOut
Abbreviated
The .abbreviated
style is the shortest style and abbreviates as much as possible.
formatter.unitsStyle = .abbreviated let oneMonthAgo = Calendar.current.date(byAdding: .month, value: 1, to: currentDate) ?? currentDate formatter.localizedString(for: currentDate, relativeTo: oneMonthAgo) // 1 mo. ago
Short
The .short
style is identical to the abbreviated style in English, but might generate different strings in other languages.
formatter.unitsStyle = .short let oneMonthAgo = Calendar.current.date(byAdding: .month, value: 1, to: currentDate) ?? currentDate formatter.localizedString(for: currentDate, relativeTo: oneMonthAgo) // 1 mo. ago
Full
The .full
style is the default style and uses longer names, such as month
instead of mo.
.
formatter.unitsStyle = .full let oneMonthAgo = Calendar.current.date(byAdding: .month, value: 1, to: currentDate) ?? currentDate formatter.localizedString(for: currentDate, relativeTo: oneMonthAgo) // 1 month ago
Spelled Out
The .spellOut
style is the longest style and uses spelled out versions of everything.
formatter.unitsStyle = .spellOut let oneMonthAgo = Calendar.current.date(byAdding: .month, value: 1, to: currentDate) ?? currentDate formatter.localizedString(for: currentDate, relativeTo: oneMonthAgo) // one month ago
Conclusion
In this guide, you learned about the different date formatters that are built into Apple’s platforms, and how to use them.
I hope this post was useful and taught you something new. If you have any questions or feedback, feel free to send them or email me: [email protected] .
Thanks for reading :calendar:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK