Date.Iso8601FormatStyle

This is part of the FormatStyle Deep Dive series

Very much a single purpose formatter, this allows us to output our dates as the ISO 8601 Standard for dates.

Note: This style cannot output AttributedString values by appending .attributed.


Download the Xcode Playground with all examples

See the examples as a gist


To output the base standard string, simply use the .iso8601 FormatStyle:

let twosdayDateComponents = DateComponents(
    year: 2022,
    month: 2,
    day: 22,
    hour: 2,
    minute: 22,
    second: 22,
    nanosecond: 22
)
let twosday = Calendar(identifier: .gregorian).date(from: twosdayDateComponents)!

twosday.formatted(.iso8601) // "2022-02-22T09:22:22Z"

If you’re needing to conform to a slightly different variant of the standard (thanks server devs), you have the ability to use the Date.ISO8601FormatStyle initializer to modify set parameters:

let isoFormat = Date.ISO8601FormatStyle(
    dateSeparator: .dash,
    dateTimeSeparator: .standard,
    timeSeparator: .colon,
    timeZoneSeparator: .colon,
    includingFractionalSeconds: true,
    timeZone: TimeZone(secondsFromGMT: 0)!
)

isoFormat.format(twosday) // "2022-02-22T09:22:22.000Z"

Date.ISO8601FormatStyle.DateSeparator can be:

Date.ISO8601FormatStyle.DateTimeSeparator can be:

Date.ISO8601FormatStyle.TimeSeparator and Date.ISO8601FormatStyle.TimeZoneSeparator can be:

And you can use the same custom FormatStyle implementation to simplify things:

struct ISO8601Variant: FormatStyle {
    typealias FormatInput = Date
    typealias FormatOutput = String

    static let isoFormat = Date.ISO8601FormatStyle(
        dateSeparator: .dash,
        dateTimeSeparator: .standard,
        timeSeparator: .colon,
        timeZoneSeparator: .colon,
        includingFractionalSeconds: true,
        timeZone: TimeZone(secondsFromGMT: 0)!
    )

    func format(_ value: Date) -> String {
        ISO8601Variant.isoFormat.format(value)
    }
}

extension FormatStyle where Self == ISO8601Variant {
    static var iso8601Variant: ISO8601Variant { .init() }
}

twosday.formatted(.iso8601Variant) // "2022-02-22T09:22:22.000Z"

Download the Xcode Playground with all examples

See the examples as a gist


Tags: