ISO8601DateFormatter — ay isang Foundation na klase sa iOS at macOS, na idinisenyo para sa pag-format at pag-parse ng mga petsa sa internasyonal na pamantayang ISO 8601. Ayon sa Apple Developer Documentation, 2024, ISO8601DateFormatter ay awtomatikong nagpoproseso ng mga format na may millisecond, time zone, at fraction ng segundo nang hindi kinakailangang manu-manong magtakda ng DateFormat. Hindi tulad ng DateFormatter, ang klase na ito ay hindi nakadepende sa Locale at TimeZone — ito ay gumagana nang mahigpit ayon sa detalye ng ISO 8601, na ginagawang perpekto para sa pagpapalitan ng mga petsa sa pagitan ng server at client. Ang klase ay available simula iOS 10 at macOS 10.12.
Mga pangunahing punto
ISO8601DateFormatter — ay isang espesyalisadong subclass ng Formatter sa Foundation na nagpapatupad ng bidirectional na conversion sa pagitan ng Date at isang string sa ISO 8601 na format. Ang pamantayang ISO 8601 (International Standard for the Representation of Dates and Times) ay tumutukoy sa internasyonal na format para sa pagpapalitan ng mga petsa at oras: 2024-07-21T14:30:00+00:00. Hindi tulad ng DateFormatter, ang klase na ito ay hindi nangangailangan ng pagtukoy ng dateFormat at awtomatikong tinutukoy ang istraktura ng string batay sa ibinigay na mga opsyon.
Ang mga pangunahing bentahe ng ISO8601DateFormatter kumpara sa DateFormatter: kawalan ng pagdepende sa locale (ang pag-parse ay gumagana nang pareho sa anumang device), built-in na suporta para sa mga fraction ng segundo (na may anumang bilang ng mga decimal) at awtomatikong pagtukoy ng format batay sa mga naipasa na opsyon. Ang klase ay tama ring humahawak ng Z-suffix (pagtatalaga ng UTC), mga time zone sa format na +HH:mm at pinababang presisyon (petsa lamang walang oras).
Ayon sa ISO Specification (ISO 8601-1:2019), ang pamantayan ay sumusuporta sa apat na antas ng presisyon: taon (2024), taon-buwan (2024-07), buong petsa (2024-07-21) at petsa-oras na may time zone (2024-07-21T14:30:00+00:00). Sinasaklaw ng ISO8601DateFormatter ang lahat ng antas na ito sa pamamagitan ng kumbinasyon ng mga format na opsyon, na nagpapalaya sa developer mula sa manu-manong pagbuo ng dateFormat string.
Prinsipyo ng paggana ng ISO8601DateFormatter ay batay sa kumbinasyon ng mga bit na opsyon (formatOptions), na ang bawat isa ay nag-a-activate ng partikular na bahagi ng petsa o oras sa output. Halimbawa, ang opsyon na .withFullDate ay nag-a-activate ng taon, buwan at araw; .withTime — oras, minuto at segundo. Sa pamamagitan ng pagsasama-sama ng mga opsyon, nakukuha ng developer ang gustong antas ng presisyon nang hindi nagsusulat ng dateFormat string.
Sa loob, ginagamit ng ISO8601DateFormatter ang ICU library para sa pag-parse, ngunit may nakapirming mga panuntunan ng ISO 8601. Nangangahulugan ito na binabalewala nito ang mga setting ng Locale at TimeZone na naka-install sa device — ang resulta ay palagiang mahuhulaan. Para sa pagtatakda ng time zone, ginagamit ang property na timeZone, na default ay katumbas ng UTC. Kung ang timeZone ay nakatakda sa nil, ginagamit ang lokal na oras ng device.
| Opsyon | Paglalarawan | Halimbawa ng output |
|---|---|---|
| .withFullDate | Taon, buwan, araw | 2024-07-21 |
| .withTime | Oras, minuto, segundo | 14:30:00 |
| .withMilliseconds | Fraction ng segundo (hanggang 3 karakter) | .123 |
| .withFractionalSeconds | Fraction ng segundo (anumang presisyon) | .123456 |
| .withTimeZone | Time zone | +03:00 |
| .withColonSeparatorInTimeZone | Separator : sa time zone | +03:00 (sa halip na +0300) |
| .withInternetDateTime | Buong format (date + time + tz) | 2024-07-21T14:30:00+00:00 |
Pagsasama-sama ng mga opsyon: Ang .withInternetDateTime ay katumbas ng pagsasama ng .withFullDate, .withTime at .withTimeZone. Para sa pag-parse ng mga string na may millisecond, idagdag ang .withFractionalSeconds. Mahalagang tandaan na ang .withMilliseconds ay naglilimita sa mga fraction ng segundo sa tatlong karakter, habang ang .withFractionalSeconds ay sumusuporta sa anumang presisyon — mula isa hanggang siyam na digit pagkatapos ng decimal point.
Mga format na opsyon ng ISO8601DateFormatter ay nahahati sa tatlong grupo: mga bahagi ng petsa (withFullDate, withYear, withMonth, withDay, withWeekOfYear), mga bahagi ng oras (withTime, withHours, withMinutes, withSeconds) at mga karagdagang setting (withMilliseconds, withFractionalSeconds, withTimeZone, withColonSeparatorInTimeZone, withDashSeparatorInDate, withFullTime). Sa pamamagitan ng pagsasama-sama ng mga ito, maaaring makuha ang halos anumang subformat ng ISO 8601.
Mahalagang nuance: Ang .withFractionalSeconds at .withMilliseconds ay mutually exclusive — kung parehong nakatakda, ang .withFractionalSeconds ang ilalapat. Para sa pag-parse ng mga millisecond mula sa data ng server, inirerekomenda ang .withFractionalSeconds, dahil maraming server ang nagpapadala ng mga fraction ng segundo na may tatlo, anim o siyam na karakter, at ang .withFractionalSeconds ay humahawak ng anumang haba.
import Foundation
// I-configure ang ISO8601DateFormatter
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone(secondsFromGMT: 0)
// Iba't ibang kumbinasyon ng format na opsyon
formatter.formatOptions = [.withFullDate]
let dateOnly = formatter.string(from: Date())
print("Petsa: \(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("Buong: \(full)")
// I-parse ang string na may millisecond
let serverString = "2024-07-21T14:30:00.123456+03:00"
if let parsed = formatter.date(from: serverString) {
print("Na-parse: \(parsed)")
}
Pangunahing paggamit ng ISO8601DateFormatter ay bumagsak sa paggawa ng instance, pagtatakda ng timeZone (inirerekomenda ang UTC para sa data ng server) at formatOptions, pagkatapos ay maaaring tawagan ang string(from:) para sa pag-format at date(from:) para sa pag-parse. Hindi tulad ng DateFormatter, hindi kailangang mag-alala tungkol sa Locale — binabalewala ng klase ang mga regional setting.
import Foundation
let formatter = ISO8601DateFormatter()
// I-parse ang iba't ibang ISO 8601 na format
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("Na-parse '\(str)': \(autoParsed)")
} else {
// Gamitin ang withFullDate para sa mga string na petsa lamang
formatter.formatOptions = [.withFullDate]
if let fallback = formatter.date(from: str) {
print("Fallback na-parse '\(str)': \(fallback)")
}
formatter.formatOptions = [.withInternetDateTime]
}
}
// I-serialize sa RFC 3339 (GitHub API)
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let rfc3339 = formatter.string(from: Date())
print("RFC 3339: \(rfc3339)")
Pag-parse ng mga petsa na may fractional second na may variable na haba — tampok ng maraming modernong API. Ang server ay maaaring magpadala ng parehong 2024-07-21T14:30:00.123Z (3 karakter) at 2024-07-21T14:30:00.123456Z (6 na karakter). Ang ISO8601DateFormatter na may opsyon na .withFractionalSeconds ay hahawak ng parehong variant nang tama, habang ang DateFormatter na may dateFormat = “yyyy-MM-dd’T’HH:mm:ss.SSSZ” ay magpoproseso lamang ng tatlong-digit na millisecond.
import Foundation
let variantFormatter = ISO8601DateFormatter()
variantFormatter.formatOptions = [
.withInternetDateTime,
.withFractionalSeconds
]
// Iba't ibang presisyon ng fractional second
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)")
}
}
// Gamitin ang withMilliseconds (3 digit lamang)
variantFormatter.formatOptions = [
.withInternetDateTime,
.withMilliseconds
]
let milliParsed = variantFormatter.string(from: Date())
print("May millisecond: \(milliParsed)")
Pagsubok sa pag-parse ng lahat ng variant: ang code sa itaas ay nagpapakita na ang ISO8601DateFormatter na may .withFractionalSeconds ay matagumpay na nagpoproseso ng mga fraction ng segundo ng anumang haba mula 1 hanggang 9 na karakter. Ito ay mahalaga para sa compatibility sa iba't ibang server platform: ang .NET ay madalas na bumubuo ng 7 karakter (100-nanosecond ticks), Python — 6, Java — 3 o 9 depende sa bersyon.
DateFormatter ay maaari ring mag-parse ng ISO 8601, ngunit nangangailangan ng manu-manong pagtatakda ng dateFormat, locale at timeZone. Ang pangunahing problema ay ang DateFormatter ay nakadepende sa Locale, at kung hindi nakatakda ang en_US_POSIX, ang pag-parse ay maaaring masira sa mga user mula sa mga rehiyon na may hindi karaniwang mga format ng petsa. Nilulutas ng ISO8601DateFormatter ang problemang ito sa antas ng arkitektura: hindi ito gumagamit ng Locale.
| Parameter | ISO8601DateFormatter | DateFormatter |
|---|---|---|
| Pagtatakda ng Locale | Hindi kinakailangan (binabalewala) | en_US_POSIX sapilitan |
| DateFormat | Awtomatiko (sa pamamagitan ng mga opsyon) | Manu-manong format string |
| Fractional second | Anumang presisyon (.withFractionalSeconds) | Fixed SSS |
| Z-suffix | Tamang hinahawakan | Sa pamamagitan ng dateFormat |
| Pagganap | Mas mataas (espesyalisado) | Mas mababa (pangkalahatan) |
| Pamantayan | ISO 8601 lamang | Anumang format |
| Bersyon ng iOS | iOS 10+ | iOS 2+ |
Kailan gagamitin ang DateFormatter: kung kailangan mag-format ng petsa sa hindi ISO 8601 na format (halimbawa, „Hulyo 21, 2024” para sa UI) o kung kinakailangan ang suporta para sa iOS 9 at mas luma. Para sa lahat ng gawain ng pagpapalitan ng petsa sa server, gamitin ang ISO8601DateFormatter — ito ay mas ligtas, mas mahusay sa pagganap, at nangangailangan ng mas kaunting code. Ang DateFormatter para sa ISO 8601 ay pinagmumulan ng mga potensyal na bug na nauugnay sa locale at regional setting.
Paglipat mula DateFormatter patungo sa ISO8601DateFormatter: palitan ang paggawa ng DateFormatter + pagtatakda ng dateFormat + locale + timeZone ng paggawa ng ISO8601DateFormatter + pagtatakda ng formatOptions + timeZone. Ang pag-parse ng string ay nananatiling hindi nagbabago sa pamamagitan ng date(from:). Para sa backward compatibility, maaaring gumamit ng #available(iOS 10, *) na may fallback sa DateFormatter.
Nakalimutang pagtatakda ng formatOptions ay nagiging sanhi ng paggamit ng formatter ng default na halaga — .withInternetDateTime. Kung ang server ay nagpapadala lamang ng petsa nang walang oras (2024-07-21), ang pag-parse ay magbabalik ng nil. Palaging suriin na ang formatOptions ay sumasaklaw sa lahat ng posibleng format na maaaring dumating mula sa server. Para sa mga API na may variable na format, gumamit ng fallback na pagtatangka na may iba't ibang kumbinasyon ng opsyon.
Pagkalito sa pagitan ng withMilliseconds at withFractionalSeconds — karaniwang pagkakamali sa pag-parse ng mga petsa na may fraction ng segundo. Ang withMilliseconds ay umaasa ng eksaktong 3 digit pagkatapos ng decimal point. Kung ang server ay nagpadala ng 6 na digit (microsecond), ang pag-parse gamit ang withMilliseconds ay mabibigo. Gamitin ang .withFractionalSeconds para sa compatibility sa anumang bilang ng mga karakter. Ang .withFractionalSeconds ay lumitaw sa iOS 13; para sa mas lumang mga bersyon, gamitin ang DateFormatter na may dateFormat.
Pagwawalang-bahala sa time zone — isa pang karaniwang problema. Kung ang server ay nagpadala ng petsa na may time zone (+03:00) at ang formatter ay nakatakda sa UTC, ang pag-parse ay hindi mabibigo, ngunit ang resulta ay nasa UTC. Ang mga developer ay madalas na umaasa na ang Date ay magpapanatili ng time zone, ngunit ang Date ay isang absolute moment sa oras at hindi nag-iimbak ng impormasyon ng time zone. Para sa tamang pagpapakita, i-save ang time zone nang hiwalay o gumamit ng ISO8601DateFormatter na may tamang timeZone.
Ayon sa Apple Forum (2024), humigit-kumulang 20% ng mga tanong tungkol sa ISO8601DateFormatter ay nauugnay sa format kung saan ang mga segundo ay opsyonal. Ang pamantayang ISO 8601 ay nagpapahintulot ng format na walang segundo: 2024-07-21T14:30+03:00. Ang ISO8601DateFormatter na may .withInternetDateTime ay hindi sumusuporta sa format na ito — para sa pag-parse nito ay kinakailangan ang DateFormatter na may dateFormat = „yyyy-MM-dd’T’HH:mmZ”. Ang limitasyong ito ay dapat isaalang-alang kapag nagtatrabaho sa mga API na gumagamit ng pinaikling format ng oras.
Mga madalas itanong
ISO8601DateFormatter — espesyalisadong Foundation na klase para sa pag-format at pag-parse ng mga petsa sa ISO 8601 na format, available mula iOS 10. Awtomatikong nagpoproseso ng mga karaniwang format nang walang manu-manong pagtatakda ng dateFormat.
ISO8601DateFormatter ay hindi nakadepende sa Locale, gumagamit ng mga opsyon sa halip na dateFormat, at tama na humahawak ng mga fraction ng segundo ng anumang haba. Ang DateFormatter ay unibersal ngunit nangangailangan ng manu-manong configuration at madaling kapitan ng mga bug na nauugnay sa regional setting.
Gamitin ang opsyon na .withFractionalSeconds — sumusuporta sa 1 hanggang 9 na karakter pagkatapos ng decimal point. Huwag gamitin ang .withMilliseconds kung ang presisyon ay maaaring mag-iba. Ang .withFractionalSeconds ay available mula iOS 13.
Default na UTC. Para baguhin ito, itakda ang property na timeZone. Kung ang timeZone = nil, ang lokal na oras ng device ang gagamitin. Kapag nag-parse ng string na may explicit na time zone sa format na +HH:MM, awtomatikong isasaalang-alang ito ng formatter.
Dahil ang default na formatOptions = .withInternetDateTime, na umaasa ng petsa + oras + time zone. Para sa pag-parse ng petsa lamang, itakda ang formatOptions = [.withFullDate]. Para suportahan ang parehong variant, gumamit ng fallback na may iba't ibang opsyon.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din