A structure that creates a locale-appropriate string representation of a date instance and converts strings of dates and times into date instances.
A date format style shares the date and time formatting pattern preferred by the user's locale for formatting and parsing.
When you want to apply a specific formatting style to a single ``Date`` instance, use ``Date/FormatStyle``. For other instances, use the following:
- When working with date representations in ISO 8601 format, use ``Date/ISO8601FormatStyle``.
- To represent an interval between two date instances, use ``Date/RelativeFormatStyle``.
- To represent two dates as a pair, for example to get output that looks like `10/21/1985 1:45 PM - 9/13/2015 6:33 PM`, use ``Date/IntervalFormatStyle``.
### Formatting String Representations of Dates and Times
``Date/FormatStyle`` provides a variety of localized presets and configuration options to create user-visible representations of dates and times from instances of ``Date``.
When displaying a date to a user, use the ``Date/formatted(date:time:)`` instance method. Set the date and time styles of the date format style separately, according to your particular needs.
For example, to create a string with a full date and no time representation, set the ``DateStyle`` to ``DateStyle/complete`` and the ``TimeStyle`` to ``TimeStyle/omitted``. Conversely, to create a string representing only the time for the current locale and time zone, set the date style to ``DateStyle/omitted`` and the time style to ``TimeStyle/complete``, as the following code illustrates:
```swift
let birthday = Date()
birthday.formatted(date: .complete, time: .omitted) // Sunday, January 17, 2021
birthday.formatted(date: .omitted, time: .complete) // 4:03:12 p.m. CST
```
The results shown are for locale set to `en_US` and time zone set to `CST`.
You can create string representations of a ``Date`` instance with various levels of brevity using preset date and time styles. The following example shows date styles of ``DateStyle/long``, ``DateStyle/abbreviated``, and ``DateStyle/numeric``, and time styles of ``TimeStyle/shortened``, ``TimeStyle/standard``, and ``TimeStyle/complete``:
```swift
let birthday = Date()
birthday.formatted(date: .long, time: .shortened) // January 17, 2021, 4:03 PM
birthday.formatted(date: .abbreviated, time: .standard) // Jan 17, 2021, 4:03:12 PM
birthday.formatted(date: .numeric, time: .complete) // 1/17/2021, 4:03:12 PM CST
birthday.formatted() // Jan 17, 2021, 4:03 PM
```
The default date style is ``DateStyle/abbreviated`` and the default time style is ``TimeStyle/shortened``.
For full customization of the string representation of a date, use the ``Date/formatted(_:)`` instance method of ``Date`` and provide a ``Date/FormatStyle`` instance.
You can apply more customization of the date and time components and their representation in your app by appying a series of convenience modifiers to your format style. The following example applies a series of modifiers to the format style to precisely define the formatting of the year, month, day, hour, minute, and timezone components of the resulting string. The ordering of the date and time modifiers has no impact on the string produced.
```swift
// Call the .formatted method on an instance of Date passing in an instance of Date.FormatStyle.
let birthday = Date()
birthday.formatted(
Date.FormatStyle()
.year(.defaultDigits)
.month(.abbreviated)
.day(.twoDigits)
.hour(.defaultDigits(amPM: .abbreviated))
.minute(.twoDigits)
.timeZone(.identifier(.long))
.era(.wide)
.dayOfYear(.defaultDigits)
.weekday(.abbreviated)
.week(.defaultDigits)
)
// Sun, Jan 17, 2021 Anno Domini (week: 4), 11:18 AM America/Chicago
```
``Date/FormatStyle`` provides a convenient factory variable, ``FormatStyle/dateTime``, used to shorten the syntax when applying date and time modifiers to customize the format, as in the following example:
```swift
let localeArray = ["en_US", "sv_SE", "en_GB", "th_TH", "fr_BE"]
for localeID in localeArray {
print(meetingDate.formatted(.dateTime
.day(.twoDigits)
.month(.wide)
.weekday(.short)
.hour(.conversationalTwoDigits(amPM: .wide))
.locale(Locale(identifier: localeID))))
}
// Th, November 12, 7 PM
// to 12 november 19
// Th 12 November, 19
// พฤ. 12 พฤศจิกายน 19
// je 12 novembre, 19 h
```
### Parsing Dates and Times
To parse a ``Date`` instance from an input string, use a date parse strategy. For example:
```swift
let inputString = "Archive for month 8, archived on day 23 - complete."
let strategy = Date.ParseStrategy(format: "Archive for month \(month: .defaultDigits), archived on day \(day: .twoDigits) - complete.", locale: Locale(identifier: "en_US"), timeZone: TimeZone(abbreviation: "CDT")!)
if let date = try? Date(inputString, strategy: strategy) {
print(date.formatted()) // "Aug 23, 2000 at 12:00 AM"
}
```
The time defaults to midnight local time unless explicitly defined.
The parse instance method attempts to parse a provided string into an instance of date using the source date format style. The function throws an error if it can't parse the input string into a date instance.
You can use ``Date/FormatStyle`` for round-trip formatting and parsing in a locale-aware manner. This date format style guides parsing the date instance from an input string, as the following code demonstrates:
```swift
let birthdayFormatStyle = Date.FormatStyle()
.year(.defaultDigits)
.month(.abbreviated)
.day(.twoDigits)
.hour(.defaultDigits(amPM: .abbreviated))
.minute(.twoDigits)
.timeZone(.identifier(.long))
.era(.abbreviated)
.weekday(.abbreviated)
let yourBirthdayString = "Mon, Feb 17, 1997 AD, 1:27 AM America/Chicago"
// Create a date instance from a string representation of a date.
let yourBirthday = try? birthdayFormatStyle.parse(yourBirthdayString)
// Feb 17, 1997 at 1:27 AM
```
The following round-trip date formatting example uses a date format style to create a locale-aware string representation of a date instance. Then, the date format style guides parsing the newly created string into a new date instance.
```swift
let myFormat = Date.FormatStyle()
.year()
.day()
.month()
.locale(Locale(identifier: "en_US"))
let dateString = Date().formatted(myFormat)
// "Feb 17, 2021" for the "en_US" locale
print(dateString) // Feb 17, 2021
if let anniversary = try? Date(dateString, strategy: myFormat) {
print(anniversary.formatted(myFormat)) // Feb 17, 2021
print(anniversary.formatted()) // 2/17/2021, 12:00 AM
} else {
print("Can't parse string into date with this format.")
}
```
After this code executes, `anniversary` contains a ``Date`` instance parsed from `dateString`.
### Applying Format Styles Repeatedly
Once you create a date format style, you can use it to format dates multiple times.
You can use a format style to parse a set of date instances from a set of string representations of dates. Then, use another format style, applied repeatedly, to produce more detailed string representations of those dates for a different locale. For example:
```swift
func formatIntroDates() {
let inputFormat = Date.FormatStyle()
.locale(Locale(identifier: "en_GB"))
.year()
.month()
.day()
// Parse string inputs into date instances.
guard let productIntroDate = try? Date("9 Jan 2007", strategy: inputFormat) else { return }
guard let anotherIntroDate = try? Date("27 Jan 2010", strategy: inputFormat) else { return }
guard let conferenceDate = try? Date("7 Jun 2021", strategy: inputFormat) else { return }
let outputFormat = Date.FormatStyle() // Define format style for string output.
.locale(Locale(identifier: "en_US"))
.year()
.month(.wide)
.day(.twoDigits)
.weekday(.abbreviated)
// Apply the output format on the three dates below.
print(outputFormat.format(conferenceDate)) // Mon, June 07, 2021
print(outputFormat.format(anotherIntroDate)) // Wed, January 27, 2010
print(outputFormat.format(productIntroDate)) // Tue, January 09, 2007
}
```
Members (33)
get · iOS 18.0+
attributedStyle
TypeScript
get attributedStyle(): Date_FormatStyle_Attributed
Swift declaration
var attributedStyle: Date.FormatStyle.Attributed { get }
Return the type preserving attributed variant of this style.
This style attributes the formatted date with the `AttributeScopes.FoundationAttributes.DateFormatFieldAttribute`.
get · iOS 15.0+ · Deprecated in iOS 18.0
attributed
TypeScript
get attributed(): Date_AttributedStyle
Swift declaration
var attributed: Date.AttributedStyle { get }
A type-erased attributed variant of this style.
Use a ``Date/FormatStyle`` instance to customize the lexical
representation of a date as a string. Use the format style's
`attributed` property to customize the visual representation of the
date as a string. Attributed strings can represent the subcomponent
characters, words, and phrases of a string with a custom combination
of font size, weight, and color.
For example, the function below uses a date format style to create a
custom lexical representation of a date, then retrieves an attributed
string representation of the same date and applies a visual emphasis
to the year component of the date.
```swift
private func makeAttributedString() -> AttributedString {
let date = Date()
let formatStyle = Date.FormatStyle(date: .abbreviated, time: .standard)
var attributedString = formatStyle.attributed.format(date)
for run in attributedString.runs {
if let dateFieldAttribute = run.attributes.foundation.dateField,
dateFieldAttribute == .year {
attributedString[run.range].inlinePresentationIntent = [.emphasized, .stronglyEmphasized]
}
}
return attributedString
}
```
The next discretization boundary after the given input.
Use this function to determine the next "greater" input that warrants updating the formatted output.
The following example prints all possible outputs the format style can produce upwards starting
from the `startInput`:
```swift
var previousInput = startInput
while let nextInput = style.discreteInput(after: previousInput) {
print(style.format(nextInput))
previousInput = nextInput
}
```
- Returns: For most `input`s, the method returns the "smallest" value "greater" than
`input` for which the style produces a different ``FormatStyle/FormatOutput``, or `nil`
if no such value exists. For some input values, the function may also return a value "greater" than
`input` for which the style still produces the same ``FormatStyle/FormatOutput`` as for
`input`.
The next discretization boundary before the given input.
Use this function to determine the next "smaller" input that warrants updating the formatted output.
The following example prints all possible outputs the format style can produce downwards starting
from the `startInput`:
```swift
var previousInput = startInput
while let nextInput = style.discreteInput(before: previousInput) {
print(style.format(nextInput))
previousInput = nextInput
}
```
- Returns: For most `input`s, the method returns the "greatest" value "smaller" than
`input` for which the style produces a different ``FormatStyle/FormatOutput``, or `nil`
if no such value exists. For some input values, the function may also return a value "smaller" than
`input` for which the style still produces the same ``FormatStyle/FormatOutput`` as for
`input`.
Creates a new `FormatStyle` with the given configurations.
- Parameters:
- date: The date style for formatting the date.
- time: The time style for formatting the date.
- locale: The locale to use when formatting date and time values.
- calendar: The calendar to use for date values.
- timeZone: The time zone with which to specify date and time values.
- capitalizationContext: The capitalization formatting context used when formatting date and time values.
- Note: Always specify the date style, time style, or the date components to be included in the formatted string with the symbol modifiers. Otherwise, an empty string will be returned when you use the instance to format a `Date`.
The next input value after the given input.
Use this function to determine if the return value provided by ``discreteInput(before:)`` is
precise enough for your use case for any input `y`:
```swift
guard let x = style.discreteInput(before: y) else {
return
}
let z = style.input(after: x) ?? y
```
If the distance between `x` and `z` is too large for the precision you require, you may want
to manually probe ``FormatStyle/format(_:)`` at a higher rate in that interval, as there is
no guarantee for what the output will be in that interval.
- Returns: The next "greater" input value that can be represented by
``FormatStyle/FormatInput`` or an underlying representation the format style uses
internally.
The next input value before the given input.
Use this function to determine if the return value provided by ``discreteInput(after:)`` is
precise enough for your use case for any input `y`:
```swift
guard let x = style.discreteInput(after: y) else {
return
}
let z = style.input(before: x) ?? y
```
If the distance between `z` and `x` is too large for the precision you require, you may want
to manually probe ``FormatStyle/format(_:)`` at a higher rate in that interval, as there is
no guarantee for what the output will be in that interval.
- Returns: The next "smalller" input value that can be represented by
``FormatStyle/FormatInput`` or an underlying representation the format style uses
internally.
Change the representation of the month in the format.
- Parameter format: Set the symbol representation or pass `nil` to remove it.
method · iOS 15.0+
parse
TypeScript
parse(value: string): globalThis.Date
Swift declaration
func parse(_ value: String) throws -> Date
Parses a string into a date.
The date format style guides parsing the date instance from an input
string, as the example below illustrates.
```swift
let birthdayFormatStyle = Date.FormatStyle()
.year(.defaultDigits)
.month(.abbreviated)
.day(.twoDigits)
.hour(.defaultDigits(amPM: .abbreviated))
.minute(.twoDigits)
.timeZone(.identifier(.long))
.era(.abbreviated)
.weekday(.abbreviated)
let yourBirthdayString = "Mon, Feb 17, 1997 AD, 1:27 AM America/Chicago"
let yourBirthday = try? birthdayFormatStyle.parse(yourBirthdayString)
// Feb 17, 1997 at 1:27 AM
```
- Parameter value: The string to parse.
- Returns: An instance of `Date` parsed from the input string.
method · iOS 15.0+
format
TypeScript
format(value: globalThis.Date): string
Swift declaration
func format(_ value: Date) -> String
Creates a locale-aware string representation from a date value.
Once you create a style, you can use it to format dates multiple times.
The following example creates a format style to guide parsing a set of
string representations of dates. It also creates a second format style,
applying it repeatedly to produce more detailed string representations of
those dates for a different locale.
```swift
let inputFormat = Date.FormatStyle()
.locale(Locale(identifier: "en_GB"))
.year()
.month()
.day()
let iphoneIntroductionDate = try! Date("9 Jan 2007", strategy: inputFormat)
let ipadIntroductionDate = try! Date("27 Jan 2010", strategy: inputFormat)
let wwdc2021Date = try! Date("7 Jun 2021", strategy: inputFormat)
let outputFormat = Date.FormatStyle()
.locale(Locale(identifier: "en_US"))
.year()
.month(.wide)
.day(.twoDigits)
.weekday(.abbreviated)
print(outputFormat.format(wwdc2021Date))
// Mon, June 07, 2021
print(outputFormat.format(ipadIntroductionDate))
// Wed, January 27, 2010
print(outputFormat.format(iphoneIntroductionDate))
// Tue, January 09, 2007
```
- Parameter value: The date to format.
- Returns: A string representation of the date.
get · iOS 15.0+
locale
TypeScript
get locale(): Locale
Swift declaration
var locale: Locale
The locale to use when formatting date and time values.
The default value is `autoupdatingCurrent`. If you set this property
to `nil`, the formatter resets to using `autoupdatingCurrent`.
set · iOS 15.0+
locale
TypeScript
set locale(value: Locale)
Swift declaration
var locale: Locale
The locale to use when formatting date and time values.
The default value is `autoupdatingCurrent`. If you set this property
to `nil`, the formatter resets to using `autoupdatingCurrent`.
method · iOS 15.0+
locale
TypeScript
locale9650(locale: Locale): Date_FormatStyle
Swift declaration
func locale(_ locale: Locale) -> Date.FormatStyle
Modifies the date format style to use the specified locale.
- Parameter locale: The locale to use when formatting a date.
- Returns: A date format style with the provided locale.
Processes the input string within the specified bounds, beginning at the given index, and returns the end position of the match and the produced output.
Don't call this method directly. Regular expression matching and capture
calls it automatically when matching substrings.
- Parameters:
- input: An input string to match against.
- index: The index within `input` at which to begin searching.
- bounds: The bounds within `input` in which to search.
- Returns: The upper bound where the match terminates and a matched instance, or `nil` if there isn't a match.