12. Juli 2019

Datumsangaben in Swift formatieren

Vorgefertigte Datumsstile

Mit der Foundation-Klasse DateFormatter können Datumsangaben bequem formatiert werden. Dabei gibt es einige vorgefertige Formatierungs-Stile zur Auswahl - es empfiehlt sich, diese zu verwenden, da die Lokalisierung in andere Sprachen damit automatisch funktioniert (jede Sprache hat eigene Regeln zur Formatierung von Datumsangaben, einige Regionen haben auch ganz eigene Kalender-Logiken):

let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .medium
let formattedString = formatter.string(for: Date())

Folgende Stile gibt es zur Auswahl:

date time
.short 12.07.19 17:09
.medium 12.07.2019 17:09:12
.long 12. Juli 2019 17:09:12 MESZ
.full Freitag, 12. Juli 2019 17:09:12 Mitteleuropäische Sommerzeit

ISO 8601

Für den Austausch von Datumswerten empfiehlt sich die Verwendung des ISO 8601-Formates - dies wird seit iOS 10 nativ unterstützt:

let isoFormatter = ISO8601DateFormatter()
isoFormatter.timeZone = TimeZone.current
isoFormatter.string(from: Date())
isoFormatter.date(from: "2019-07-12T17:09:12+02:00")

Eigene Datumsformate

Mit der Eigenschaft dateFormat können eigene Datumsformate definiert werden (die dabei verwendbaren Patterns/Formatierungsregeln können im Unicode-Standard nachgelesen werden):

let customFormatter = DateFormatter()
customFormatter.dateFormat = "eeee, dd.MM."
let customString = customFormatter.string(for: Date())

Tipp: Datumsformate zentral definieren

Seit iOS 10 sind DateFormatter thread-safe. Daher empfiehlt es sich, anwendungsweit benötigte Datumsformatierungen einheitlich und zentral zu definieren, z.B. in einer Datei DateFormats.swift:

struct DateFormats {
    
    static var dateOnlyFormatter: DateFormatter = {
        let df = DateFormatter()
        df.dateStyle = .full
        df.timeStyle = .none
        return df
    }()
    
    static var timeOnlyFormatter: DateFormatter = {
        let df = DateFormatter()
        df.timeStyle = .short
        df.dateStyle = .none
        return df
    }()

}

Tipp: Datumswerte formatieren via String Interpolation

Mit einer Extension zu DefaultStringInterpolation kann eine Funktion definiert werden, die es erlaubt, Datumswerte via String Interpolation zu formatieren:

extension DefaultStringInterpolation {
    
    mutating func appendInterpolation(_ value: Date, formatter: DateFormatter) {
        self.appendInterpolation(formatter.string(from: value))
    }
    
}

Dies erlaubt das Formatieren eines Datumswertes beim Einsetzen in eine Zeichenkette - die Parameter der appendInterpolation-Funktion werden innerhalb des \(...)-Ausdrucks geschrieben:

let result = "Heute ist der \(Date(), formatter: DateFormats.dateOnlyFormatter)"