ISO8601DateFormatter: klíčové pojmy a formátování ISO 8601

Autor: IT Sectr Publikováno: 2026-07-13 Doba čtení: 9 min

ISO8601DateFormatter — je třída Foundation v iOS a macOS, určená pro formátování a parsování dat v mezinárodním standardu ISO 8601. Podle Apple Developer Documentation, 2024, ISO8601DateFormatter automaticky zpracovává formáty s milisekundami, časovými pásmy a zlomky sekund bez nutnosti ručně nastavovat DateFormat. Na rozdíl od DateFormatter tato třída není závislá na Locale a TimeZone — pracuje přísně podle specifikace ISO 8601, což ji činí ideální pro výměnu dat mezi serverem a klientem. Třída je dostupná od iOS 10 a macOS 10.12.

Hlavní body

  • ISO8601DateFormatter — třída Foundation pro formátování dat podle standardu ISO 8601
  • Nevyžaduje DateFormat — formát je určen automaticky na základě nastavení možností
  • Lokálně ne nezávislý — pracuje stejně na všech zařízeních bez nastavení Locale
  • Podpora milisekund — zpracovává zlomky sekund libovolné přesnosti (tři, šest a více znaků)
  • Možnosti formátování — withFullDate, withTime, withMilliseconds, withTimeZone a další řídí komponenty výstupu

Co je ISO8601DateFormatter?

ISO8601DateFormatter — je specializovaná podtřída Formatter ve Foundation, která implementuje obousměrnou konverzi mezi Date a řetězcem ve formátu ISO 8601. Standard ISO 8601 (International Standard for the Representation of Dates and Times) definuje mezinárodní formát pro výměnu dat a času: 2024-07-21T14:30:00+00:00. Na rozdíl od DateFormatter tato třída nevyžaduje zadání dateFormat a automaticky určuje strukturu řetězce na základě daných možností.

Hlavní výhody ISO8601DateFormatter oproti DateFormatter: absence závislosti na locale (parsování funguje stejně na jakémkoli zařízení), vestavěná podpora zlomků sekund (s libovolným počtem desetinných míst) a automatické určení formátu na základě předaných možností. Třída také správně zpracovává příponu Z (označení UTC), časová pásma ve formátu +HH:mm a sníženou přesnost (pouze datum bez času).

Podle ISO Specification (ISO 8601-1:2019) standard podporuje čtyři úrovně přesnosti: rok (2024), rok-měsíc (2024-07), plné datum (2024-07-21) a datum-čas s časovým pásmem (2024-07-21T14:30:00+00:00). ISO8601DateFormatter pokrývá všechny tyto úrovně kombinací možností formátu a zbavuje vývojáře nutnosti ručně konstruovat řetězec dateFormat.

Jak funguje ISO8601DateFormatter ve Foundation?

Princip fungování ISO8601DateFormatter je založen na kombinaci bitových možností (formatOptions), z nichž každá aktivuje určitou komponentu data nebo času ve výstupu. Například možnost .withFullDate aktivuje rok, měsíc a den; .withTime — hodiny, minuty a sekundy. Kombinováním možností získá vývojář požadovanou úroveň přesnosti bez psaní řetězce dateFormat.

Interně ISO8601DateFormatter používá knihovnu ICU pro parsování, ale s pevnými pravidly ISO 8601. To znamená, že ignoruje nastavení Locale a TimeZone nainstalovaná na zařízení — výsledek je vždy předvídatelný. Pro nastavení časového pásma se používá vlastnost timeZone, která je ve výchozím nastavení rovna UTC. Pokud je timeZone nastaven na nil, použije se místní čas zařízení.

MožnostPopisPříklad výstupu
.withFullDateRok, měsíc, den2024-07-21
.withTimeHodiny, minuty, sekundy14:30:00
.withMillisecondsZlomky sekund (až 3 znaky).123
.withFractionalSecondsZlomky sekund (libovolná přesnost).123456
.withTimeZoneČasové pásmo+03:00
.withColonSeparatorInTimeZoneOddělovač : v časovém pásmu+03:00 (místo +0300)
.withInternetDateTimePlný formát (date + time + tz)2024-07-21T14:30:00+00:00

Kombinování možností: .withInternetDateTime je ekvivalentní kombinaci .withFullDate, .withTime a .withTimeZone. Pro parsování řetězců s milisekundami přidejte .withFractionalSeconds. Je důležité si zapamatovat, že .withMilliseconds omezuje zlomky sekund na tři znaky, zatímco .withFractionalSeconds podporuje libovolnou přesnost — od jedné do devíti číslic za desetinnou čárkou.

Nastavení formátu ISO 8601

Možnosti formátu ISO8601DateFormatter jsou rozděleny do tří skupin: komponenty data (withFullDate, withYear, withMonth, withDay, withWeekOfYear), komponenty času (withTime, withHours, withMinutes, withSeconds) a doplňková nastavení (withMilliseconds, withFractionalSeconds, withTimeZone, withColonSeparatorInTimeZone, withDashSeparatorInDate, withFullTime). Jejich kombinací lze získat prakticky libovolný podformát ISO 8601.

Základní kombinace možností

  • .withFullDate — pouze datum: 2024-07-21. Pro parsování řetězců ve formátu YYYY-MM-DD
  • .withFullDate + .withTime — datum a čas bez časového pásma: 2024-07-21T14:30:00
  • .withInternetDateTime — plný formát: 2024-07-21T14:30:00Z nebo 2024-07-21T14:30:00+03:00
  • .withInternetDateTime + .withFractionalSeconds — se zlomky sekund: 2024-07-21T14:30:00.123456+00:00
  • .withFullDate + .withTime + .withTimeZone — plný formát bez dvojtečky v tz: 2024-07-21T14:30:00+0300

Důležitý detail: .withFractionalSeconds a .withMilliseconds se vzájemně vylučují — pokud jsou nastaveny obě, použije se .withFractionalSeconds. Pro parsování milisekund ze serverových dat se doporučuje .withFractionalSeconds, protože mnoho serverů posílá zlomky sekund se třemi, šesti nebo devíti znaky a .withFractionalSeconds zpracovává libovolnou délku.

swift
import Foundation

// Nakonfiguruj ISO8601DateFormatter
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)

// Různé kombinace možností formátu
formatter.formatOptions = [.withFullDate]
let dateOnly = formatter.string(from: Date())
print("Datum: \(dateOnly)")

formatter.formatOptions = [.withFullDate, .withTime]
let dateTime = formatter.string(from: Date())
print("DateTime: \(dateTime)")

formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let full = formatter.string(from: Date())
print("Plný: \(full)")

// Parsuj řetězec s milisekundami
let serverString = "2024-07-21T14:30:00.123456+03:00"
if let parsed = formatter.date(from: serverString) {
    print("Parsováno: \(parsed)")
}

ISO8601DateFormatter ve Swift: příklady kódu

Základní použití ISO8601DateFormatter spočívá ve vytvoření instance, nastavení timeZone (doporučuje se UTC pro serverová data) a formatOptions, poté lze volat string(from:) pro formátování a date(from:) pro parsování. Na rozdíl od DateFormatter se nemusíte starat o Locale — třída ignoruje regionální nastavení.

swift
import Foundation

let formatter = ISO8601DateFormatter()

// Parsuj různé formáty ISO 8601
let strings: [String] = [
    "2024-07-21T14:30:00Z",
    "2024-07-21T14:30:00+03:00",
    "2024-07-21T14:30:00.123Z",
    "2024-07-21"
]

for str in strings {
    if let autoParsed = formatter.date(from: str) {
        print("Parsováno '\(str)': \(autoParsed)")
    } else {
        // Použij withFullDate pro řetězce pouze s datem
        formatter.formatOptions = [.withFullDate]
        if let fallback = formatter.date(from: str) {
            print("Fallback parsováno '\(str)': \(fallback)")
        }
        formatter.formatOptions = [.withInternetDateTime]
    }
}

// Serializuj do RFC 3339 (API GitHub)
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let rfc3339 = formatter.string(from: Date())
print("RFC 3339: \(rfc3339)")

Parsování dat s zlomkovými sekundami proměnlivé délky — vlastnost mnoha moderních API. Server může odeslat jak 2024-07-21T14:30:00.123Z (3 znaky), tak 2024-07-21T14:30:00.123456Z (6 znaků). ISO8601DateFormatter s možností .withFractionalSeconds správně zpracuje obě varianty, zatímco DateFormatter s dateFormat = „yyyy-MM-dd’T’HH:mm:ss.SSSZ” zpracuje pouze tříciferné milisekundy.

swift
import Foundation

let variantFormatter = ISO8601DateFormatter()
variantFormatter.formatOptions = [
    .withInternetDateTime,
    .withFractionalSeconds
]

// Různá přesnost zlomkových sekund
let variants: [String] = [
    "2024-07-21T14:30:00.1Z",
    "2024-07-21T14:30:00.12Z",
    "2024-07-21T14:30:00.123Z",
    "2024-07-21T14:30:00.123456Z",
    "2024-07-21T14:30:00.123456789Z"
]

for variant in variants {
    if let parsed = variantFormatter.date(from: variant) {
        print("OK: \(variant) -> \(parsed)")
    } else {
        print("FAIL: \(variant)")
    }
}

// Použij withMilliseconds (pouze 3 číslice)
variantFormatter.formatOptions = [
    .withInternetDateTime,
    .withMilliseconds
]
let milliParsed = variantFormatter.string(from: Date())
print("S milisekundami: \(milliParsed)")

Testování parsování všech variant: výše uvedený kód ukazuje, že ISO8601DateFormatter s .withFractionalSeconds úspěšně zpracovává zlomky sekund libovolné délky od 1 do 9 znaků. To je důležité pro kompatibilitu s různými serverovými platformami: .NET často generuje 7 znaků (100-nanosekundové ticky), Python — 6, Java — 3 nebo 9 v závislosti na verzi.

Srovnání s DateFormatter pro ISO 8601

DateFormatter také umí parsovat ISO 8601, ale vyžaduje ruční nastavení dateFormat, locale a timeZone. Hlavním problémem je, že DateFormatter závisí na Locale, a pokud není nastaven en_US_POSIX, parsování se může pokazit u uživatelů z regionů s nestandardními formáty dat. ISO8601DateFormatter řeší tento problém na úrovni architektury: Locale nepoužívá.

ParametrISO8601DateFormatterDateFormatter
Nastavení LocaleNení vyžadováno (ignoruje)en_US_POSIX povinné
DateFormatAutomatický (přes možnosti)Ruční řetězec format
Zlomkové sekundyLibovolná přesnost (.withFractionalSeconds)Pevný SSS
Přípona ZSprávně zpracováváPřes dateFormat
VýkonVyšší (specializovaný)Nižší (obecný)
StandardPouze ISO 8601Libovolný formát
Verze iOSiOS 10+iOS 2+

Kdy použít DateFormatter: pokud potřebujete formátovat datum v ne-ISO 8601 formátu (například „21. července 2024” pro UI) nebo pokud je vyžadována podpora iOS 9 a starších. Pro všechny úkoly výměny dat se serverem použijte ISO8601DateFormatter — je bezpečnější, výkonnější a vyžaduje méně kódu. DateFormatter pro ISO 8601 je zdrojem potenciálních chyb souvisejících s locale a regionálním nastavením.

Migrace z DateFormatter na ISO8601DateFormatter: nahraďte vytvoření DateFormatter + nastavení dateFormat + locale + timeZone vytvořením ISO8601DateFormatter + nastavením formatOptions + timeZone. Parsování řetězce zůstává nezměněno přes date(from:). Pro zpětnou kompatibilitu lze použít #available(iOS 10, *) s fallbackem na DateFormatter.

Typické chyby při parsování ISO 8601

Zapomenuté nastavení formatOptions způsobí, že formatter použije výchozí hodnotu — .withInternetDateTime. Pokud server posílá pouze datum bez času (2024-07-21), parsování vrátí nil. Vždy zkontrolujte, že formatOptions pokrývají všechny možné formáty, které mohou ze serveru přijít. Pro API s proměnlivými formáty použijte fallback pokusy s různými kombinacemi možností.

Záměna withMilliseconds a withFractionalSeconds — častá chyba při parsování dat se zlomky sekund. withMilliseconds očekává přesně 3 číslice za desetinnou čárkou. Pokud server pošle 6 číslic (mikrosekundy), parsování s withMilliseconds selže. Použijte .withFractionalSeconds pro kompatibilitu s libovolným počtem znaků. .withFractionalSeconds se objevil v iOS 13; pro starší verze použijte DateFormatter s dateFormat.

Ignorování časového pásma — další častý problém. Pokud server posílá datum s časovým pásmem (+03:00) a formatter je nastaven na UTC, parsování neselže, ale výsledek bude v UTC. Vývojáři často očekávají, že Date zachová časové pásmo, ale Date je absolutní okamžik v čase a neukládá informace o časovém pásmu. Pro správné zobrazení uložte časové pásmo zvlášť nebo použijte ISO8601DateFormatter se správným timeZone.

Podle Apple Forum (2024) se asi 20% dotazů týkajících se ISO8601DateFormatter týká formátu, kde jsou sekundy volitelné. Standard ISO 8601 povoluje formát bez sekund: 2024-07-21T14:30+03:00. ISO8601DateFormatter s .withInternetDateTime tento formát nepodporuje — pro jeho parsování je zapotřebí DateFormatter s dateFormat = „yyyy-MM-dd’T’HH:mmZ”. Toto omezení je třeba vzít v úvahu při práci s API, která používají zkrácený formát času.

Často kladené otázky

Co je ISO8601DateFormatter?

ISO8601DateFormatter — specializovaná třída Foundation pro formátování a parsování dat ve formátu ISO 8601, dostupná od iOS 10. Automaticky zpracovává standardní formáty bez ručního zadání dateFormat.

Čím se ISO8601DateFormatter liší od DateFormatter?

ISO8601DateFormatter není závislý na Locale, používá možnosti místo dateFormat a správně zpracovává zlomky sekund libovolné délky. DateFormatter je univerzální, ale vyžaduje ruční konfiguraci a je náchylný k chybám souvisejícím s regionálním nastavením.

Jak zpracovávat zlomky sekund proměnlivé délky?

Použijte možnost .withFractionalSeconds — podporuje 1 až 9 znaků za desetinnou čárkou. Nepoužívejte .withMilliseconds, pokud se přesnost může měnit. .withFractionalSeconds je dostupný od iOS 13.

Jaké časové pásmo používá ISO8601DateFormatter?

Výchozí je UTC. Pro změnu nastavte vlastnost timeZone. Pokud je timeZone = nil, použije se místní čas zařízení. Při parsování řetězce s explicitním časovým pásmem ve formátu +HH:MM jej formatter automaticky zohlední.

Proč parsování data bez času vrátí nil?

Protože výchozí formatOptions = .withInternetDateTime, který očekává datum + čas + časové pásmo. Pro parsování pouze data nastavte formatOptions = [.withFullDate]. Pro podporu obou variant použijte fallback s různými možnostmi.

Shrnutí

  • ISO8601DateFormatter — specializovaná třída pro ISO 8601, bezpečnější a jednodušší než DateFormatter
  • Možnosti formátu nahrazují ruční dateFormat — kombinujte .withFullDate, .withTime, .withTimeZone
  • Nezávislý na Locale — parsování funguje stejně na všech zařízeních bez nastavení locale
  • .withFractionalSeconds zpracovává zlomky sekund libovolné přesnosti (1–9 znaků)
  • DateFormatter prohrává ve výkonu, bezpečnosti a jednoduchosti pro úkoly ISO 8601
  • Záměna možností — withMilliseconds a withFractionalSeconds nejsou zaměnitelné
  • Formát bez sekund (2024-07-21T14:30+03:00) není podporován — je potřeba DateFormatter

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také