ISO8601DateFormatter — egy Foundation osztály iOS-ben és macOS-ben, amely az ISO 8601 nemzetközi szabvány szerinti dátumok formázására és parse-olására szolgál. A Apple Developer Documentation, 2024 szerint a ISO8601DateFormatter automatikusan kezeli a milliszekundumos, időzónás és másodperc törtes formátumokat anélkül, hogy manuálisan kellene beállítani a DateFormat-ot. A DateFormatter-rel ellentétben ez az osztály nem függ a Locale-tól és TimeZone-tól — szigorúan az ISO 8601 specifikáció szerint működik, ami ideálissá teszi a szerver és kliens közötti dátumcserére. Az osztály iOS 10 és macOS 10.12-től elérhető.
Főbb pontok
ISO8601DateFormatter — a Formatter egy specializált alosztálya a Foundation-ben, amely kétirányú konverziót valósít meg a Date és egy ISO 8601 formátumú string között. Az ISO 8601 szabvány (International Standard for the Representation of Dates and Times) meghatározza a nemzetközi dátum- és időcserélő formátumot: 2024-07-21T14:30:00+00:00. A DateFormatter-rel ellentétben ez az osztály nem igényli a dateFormat megadását, és automatikusan meghatározza a string szerkezetét a megadott opciók alapján.
Az ISO8601DateFormatter fő előnyei a DateFormatter-rel szemben: a locale-tól való függetlenség (a parse-olás minden eszközön ugyanúgy működik), beépített támogatás a másodperc törtekhez (bármilyen számú tizedesjeggyel) és a formátum automatikus meghatározása a megadott opciók alapján. Az osztály helyesen kezeli a Z-utótagot (UTC jelölés), a +HH:mm formátumú időzónákat és a csökkentett pontosságot (csak dátum idő nélkül).
A ISO Specification (ISO 8601-1:2019) szerint a szabvány négy pontossági szintet támogat: év (2024), év-hónap (2024-07), teljes dátum (2024-07-21) és dátum-idő időzónával (2024-07-21T14:30:00+00:00). Az ISO8601DateFormatter ezeket a szinteket a formátumopciók kombinálásával fedi le, megszabadítva a fejlesztőt a dateFormat string manuális összeállításától.
Működési elv Az ISO8601DateFormatter bitopciók (formatOptions) kombinációján alapul, amelyek mindegyike egy adott dátum- vagy időkomponenst aktivál a kimenetben. Például a .withFullDate opció aktiválja az évet, hónapot és napot; a .withTime — az órákat, perceket és másodperceket. Az opciók kombinálásával a fejlesztő eléri a kívánt pontossági szintet anélkül, hogy dateFormat stringet kellene írnia.
Belsőleg az ISO8601DateFormatter az ICU könyvtárat használja a parse-oláshoz, de rögzített ISO 8601 szabályokkal. Ez azt jelenti, hogy figyelmen kívül hagyja az eszközön beállított Locale és TimeZone beállításokat — az eredmény mindig kiszámítható. Az időzóna beállításához a timeZone tulajdonság használatos, amely alapértelmezetten UTC-vel egyenlő. Ha a timeZone nil értékre van állítva, az eszköz helyi ideje kerül felhasználásra.
| Opció | Leírás | Példa kimenet |
|---|---|---|
| .withFullDate | Év, hónap, nap | 2024-07-21 |
| .withTime | Órák, percek, másodpercek | 14:30:00 |
| .withMilliseconds | Másodperc törtek (3 karakterig) | .123 |
| .withFractionalSeconds | Másodperc törtek (bármilyen pontosság) | .123456 |
| .withTimeZone | Időzóna | +03:00 |
| .withColonSeparatorInTimeZone | Kettőspont elválasztó az időzónában | +03:00 (+0300 helyett) |
| .withInternetDateTime | Teljes formátum (date + time + tz) | 2024-07-21T14:30:00+00:00 |
Opciók kombinálása: A .withInternetDateTime egyenlő a .withFullDate, .withTime és .withTimeZone kombinálásával. A milliszekundumos stringek parse-olásához adja hozzá a .withFractionalSeconds-t. Fontos megjegyezni, hogy a .withMilliseconds a másodperc törteket három karakterre korlátozza, míg a .withFractionalSeconds bármilyen pontosságot támogat — egy és kilenc tizedesjegy között.
Formátum opciók Az ISO8601DateFormatter három csoportra oszlik: dátumkomponensek (withFullDate, withYear, withMonth, withDay, withWeekOfYear), időkomponensek (withTime, withHours, withMinutes, withSeconds) és kiegészítő beállítások (withMilliseconds, withFractionalSeconds, withTimeZone, withColonSeparatorInTimeZone, withDashSeparatorInDate, withFullTime). Ezek kombinálásával gyakorlatilag bármilyen ISO 8601 alformátum előállítható.
Fontos árnyalat: A .withFractionalSeconds és .withMilliseconds kölcsönösen kizárják egymást — ha mindkettő be van állítva, a .withFractionalSeconds érvényesül. A szerveradatokból történő milliszekundum parse-oláshoz a .withFractionalSeconds ajánlott, mivel sok szerver három, hat vagy kilenc karakterrel küldi a másodperc törteket, és a .withFractionalSeconds bármilyen hosszt kezel.
import Foundation
// ISO8601DateFormatter konfigurálása
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)
// Különböző formátum opció kombinációk
formatter.formatOptions = [.withFullDate]
let dateOnly = formatter.string(from: Date())
print("Dátum: \(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("Teljes: \(full)")
// String parse-olása milliszekundumokkal
let serverString = "2024-07-21T14:30:00.123456+03:00"
if let parsed = formatter.date(from: serverString) {
print("Parse-olva: \(parsed)")
}
Alapvető használat Az ISO8601DateFormatter használata egy példány létrehozására, a timeZone (szerveradatokhoz UTC ajánlott) és formatOptions beállítására redukálódik, ezután meghívható a string(from:) formázáshoz és a date(from:) parse-oláshoz. A DateFormatter-rel ellentétben nem kell aggódni a Locale miatt — az osztály figyelmen kívül hagyja a regionális beállításokat.
import Foundation
let formatter = ISO8601DateFormatter()
// Különböző ISO 8601 formátumok parse-olása
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("Parse-olva '\(str)': \(autoParsed)")
} else {
// Használja a withFullDate-t csak dátum stringekhez
formatter.formatOptions = [.withFullDate]
if let fallback = formatter.date(from: str) {
print("Fallback parse-olva '\(str)': \(fallback)")
}
formatter.formatOptions = [.withInternetDateTime]
}
}
// Szerializálás RFC 3339-re (GitHub API)
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let rfc3339 = formatter.string(from: Date())
print("RFC 3339: \(rfc3339)")
Változó hosszúságú tört másodperceket tartalmazó dátumok parse-olása — számos modern API jellemzője. A szerver küldhet 2024-07-21T14:30:00.123Z (3 karakter) és 2024-07-21T14:30:00.123456Z (6 karakter) formátumot is. Az ISO8601DateFormatter a .withFractionalSeconds opcióval mindkét változatot helyesen kezeli, míg a DateFormatter a dateFormat = „yyyy-MM-dd’T’HH:mm:ss.SSSZ” beállítással csak a háromjegyű milliszekundumokat dolgozza fel.
import Foundation
let variantFormatter = ISO8601DateFormatter()
variantFormatter.formatOptions = [
.withInternetDateTime,
.withFractionalSeconds
]
// Különböző tört másodperc pontosság
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)")
}
}
// Használja a withMilliseconds-t (csak 3 számjegy)
variantFormatter.formatOptions = [
.withInternetDateTime,
.withMilliseconds
]
let milliParsed = variantFormatter.string(from: Date())
print("Milliszekundumokkal: \(milliParsed)")
Az összes változat parse-olásának tesztelése: a fenti kód bemutatja, hogy az ISO8601DateFormatter a .withFractionalSeconds segítségével sikeresen feldolgozza a másodperc törteket bármilyen, 1 és 9 karakter közötti hosszúságban. Ez fontos a különböző szerverplatformokkal való kompatibilitáshoz: a .NET gyakran 7 karaktert (100 nanomásodperces tick-eket), a Python — 6, a Java — verziótól függően 3 vagy 9 karaktert generál.
DateFormatter szintén képes parse-olni ISO 8601-et, de manuálisan kell beállítani a dateFormat, locale és timeZone értékeket. A fő probléma, hogy a DateFormatter függ a Locale-tól, és ha nincs beállítva en_US_POSIX, a parse-olás meghibásodhat a nem szabványos dátumformátumú régiókban élő felhasználóknál. Az ISO8601DateFormatter ezt a problémát architektúra szinten oldja meg: nem használ Locale-t.
| Paraméter | ISO8601DateFormatter | DateFormatter |
|---|---|---|
| Locale beállítás | Nem szükséges (figyelmen kívül hagyja) | en_US_POSIX kötelező |
| DateFormat | Automatikus (opciókon keresztül) | Manuális formátum string |
| Tört másodpercek | Bármilyen pontosság (.withFractionalSeconds) | Rögzített SSS |
| Z-utótag | Helyesen kezeli | DateFormat-en keresztül |
| Teljesítmény | Magasabb (specializált) | Alacsonyabb (általános) |
| Szabvány | Csak ISO 8601 | Bármilyen formátum |
| iOS verzió | iOS 10+ | iOS 2+ |
Mikor használjuk a DateFormatter-t: ha nem ISO 8601 formátumban kell formázni egy dátumot (például „2024. július 21.” a UI számára), vagy ha iOS 9 és régebbi verziók támogatása szükséges. Minden szerverrel történő dátumcsere feladathoz használja az ISO8601DateFormatter-t — biztonságosabb, hatékonyabb és kevesebb kódot igényel. A DateFormatter ISO 8601 esetén a locale-hoz és regionális beállításokhoz kapcsolódó potenciális hibák forrása.
Migráció DateFormatter-ről ISO8601DateFormatter-re: cserélje ki a DateFormatter létrehozását + dateFormat + locale + timeZone beállítását az ISO8601DateFormatter létrehozására + formatOptions + timeZone beállítására. A string parse-olása változatlan marad a date(from:) segítségével. Visszafelé kompatibilitáshoz használható a #available(iOS 10, *) DateFormatter-re történő fallback-kel.
Elfelejtett formatOptions beállítás azt eredményezi, hogy a formatter az alapértelmezett értéket használja — .withInternetDateTime. Ha a szerver csak dátumot küld idő nélkül (2024-07-21), a parse-olás nil-t ad vissza. Mindig ellenőrizze, hogy a formatOptions lefedje az összes lehetséges formátumot, amely a szerverről érkezhet. Változó formátumú API-khoz használjon fallback kísérleteket különböző opciókombinációkkal.
A withMilliseconds és withFractionalSeconds összekeverése — gyakori hiba a másodperc törteket tartalmazó dátumok parse-olásakor. A withMilliseconds pontosan 3 tizedesjegyet vár. Ha a szerver 6 számjegyet küld (mikroszekundumok), a withMilliseconds-szel történő parse-olás hibával végződik. Használja a .withFractionalSeconds-t bármilyen karakterszámú kompatibilitáshoz. A .withFractionalSeconds iOS 13-ban jelent meg; régebbi verziókhoz használja a DateFormatter-t dateFormat-fal.
Az időzóna figyelmen kívül hagyása — egy másik gyakori probléma. Ha a szerver időzónával küldi a dátumot (+03:00), és a formatter UTC-re van állítva, a parse-olás nem fog meghiúsulni, de az eredmény UTC-ben lesz. A fejlesztők gyakran elvárják, hogy a Date megtartsa az időzónát, de a Date egy abszolút időpillanat, és nem tárol időzóna információt. A helyes megjelenítéshez mentse az időzónát külön, vagy használja az ISO8601DateFormatter-t a megfelelő timeZone-nal.
Az Apple Forum (2024) szerint az ISO8601DateFormatter-rel kapcsolatos kérdések körülbelül 20%-a arra a formátumra vonatkozik, ahol a másodpercek opcionálisak. Az ISO 8601 szabvány engedélyezi a másodperc nélküli formátumot: 2024-07-21T14:30+03:00. Az ISO8601DateFormatter a .withInternetDateTime opcióval nem támogatja ezt a formátumot — a parse-olásához DateFormatter szükséges a dateFormat = „yyyy-MM-dd’T’HH:mmZ” beállítással. Ezt a korlátozást figyelembe kell venni a rövidített időformátumot használó API-kkal végzett munka során.
Gyakran ismételt kérdések
ISO8601DateFormatter — specializált Foundation osztály dátumok ISO 8601 formátumban történő formázásához és parse-olásához, iOS 10-től elérhető. Automatikusan kezeli a szabványos formátumokat manuális dateFormat beállítás nélkül.
ISO8601DateFormatter nem függ a Locale-tól, opciókat használ a dateFormat helyett, és helyesen kezeli a bármilyen hosszúságú másodperc törteket. A DateFormatter univerzális, de manuális konfigurációt igényel és hajlamos a regionális beállításokkal kapcsolatos hibákra.
Használja a .withFractionalSeconds opciót — 1-től 9 karakterig támogatja a tizedesjegyeket. Ne használja a .withMilliseconds-t, ha a pontosság változhat. A .withFractionalSeconds iOS 13-tól elérhető.
Alapértelmezetten UTC. Módosításához állítsa be a timeZone tulajdonságot. Ha a timeZone = nil, az eszköz helyi ideje kerül felhasználásra. +HH:MM formátumú explicit időzónával rendelkező string parse-olásakor a formatter automatikusan figyelembe veszi azt.
Mert az alapértelmezett formatOptions = .withInternetDateTime, amely dátumot + időt + időzónát vár. Csak dátum parse-olásához állítsa be a formatOptions = [.withFullDate] értéket. Mindkét változat támogatásához használjon fallback-et különböző opciókkal.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is