Detaljan vodič za JavaScript Temporal API, moderno rješenje za učinkovito rukovanje datumima i vremenima u različitim međunarodnim kontekstima.
JavaScript Temporal API: Moderno rukovanje datumom i vremenom za globalnu publiku
JavaScript `Date` objekt dugo je bio izvor frustracija za programere. Njegova promjenjivost, nedosljedan API i slaba podrška za vremenske zone doveli su do stvaranja brojnih biblioteka poput Moment.js i date-fns koje su popunjavale te praznine. Sada, s Temporal API-jem, JavaScript nudi moderno, ugrađeno rješenje za rukovanje datumima i vremenima s poboljšanom jasnoćom i preciznošću. Ovaj članak pruža sveobuhvatan pregled Temporal API-ja, fokusirajući se na njegove značajke, prednosti i upotrebu u različitim međunarodnim kontekstima.
Što je Temporal API?
Temporal API je novi, globalni objekt u JavaScriptu dizajniran da riješi nedostatke `Date` objekta. Pruža čist, nepromjenjiv (immutable) API za rad s datumima, vremenima, vremenskim zonama i kalendarskim sustavima. Ključno, cilj mu je predstaviti koncepte datuma i vremena na način koji je bliži stvarnoj upotrebi i očekivanjima, čineći internacionalizaciju znatno jednostavnijom.
Ključne značajke:
- Nepromjenjivost (Immutability): Temporal objekti su nepromjenjivi, što znači da operacije poput dodavanja dana ili mjeseci vraćaju nove objekte umjesto da mijenjaju originalni. To eliminira čest izvor grešaka i čini kod lakšim za razumijevanje.
- Jasan API: Temporal pruža dosljedan i intuitivan API za uobičajene operacije s datumom i vremenom.
- Podrška za vremenske zone: Temporal uključuje robusnu podršku za vremenske zone, omogućujući vam rad s datumima i vremenima na različitim lokacijama bez složenosti starog `Date` objekta. Koristi IANA bazu podataka vremenskih zona, osiguravajući točne i ažurne informacije.
- Kalendarski sustavi: Osim gregorijanskog kalendara, Temporal podržava alternativne kalendarske sustave, zadovoljavajući potrebe različitih kultura i regija.
- Poboljšana preciznost: Temporal nudi nanosekundnu preciznost, rješavajući ograničenja `Date` objekta temeljenog na milisekundama.
Osnovni Temporal objekti
Temporal API uvodi nekoliko novih vrsta objekata. Evo nekih od ključnih:
- `Temporal.PlainDate`: Predstavlja datum (godina, mjesec, dan) bez vremenske zone.
- `Temporal.PlainTime`: Predstavlja vrijeme (sat, minuta, sekunda, milisekunda, mikrosekunda, nanosekunda) bez datuma ili vremenske zone.
- `Temporal.PlainDateTime`: Predstavlja datum i vrijeme bez vremenske zone.
- `Temporal.ZonedDateTime`: Predstavlja datum i vrijeme s određenom vremenskom zonom.
- `Temporal.Instant`: Predstavlja točan trenutak u vremenu, mjeren u nanosekundama od Unix epohe (1. siječnja 1970. UTC).
- `Temporal.TimeZone`: Predstavlja vremensku zonu.
- `Temporal.Duration`: Predstavlja vremenski raspon (npr. 2 sata, 30 minuta).
- `Temporal.YearMonth`: Predstavlja godinu i mjesec.
- `Temporal.MonthDay`: Predstavlja mjesec i dan.
Rad s datumima
Kreiranje `Temporal.PlainDate` objekta
Da biste kreirali `Temporal.PlainDate`, možete koristiti konstruktor:
const plainDate = new Temporal.PlainDate(2024, 10, 27); // Godina, Mjesec (1-12), Dan
console.log(plainDate.toString()); // Izlaz: 2024-10-27
Također možete koristiti metodu `from`, koja prihvaća string u ISO 8601 formatu:
const plainDateFromString = Temporal.PlainDate.from('2024-10-27');
console.log(plainDateFromString.toString()); // Izlaz: 2024-10-27
Dohvaćanje komponenti datuma
Možete pristupiti pojedinačnim komponentama datuma koristeći svojstva poput `year`, `month` i `day`:
console.log(plainDate.year); // Izlaz: 2024
console.log(plainDate.month); // Izlaz: 10
console.log(plainDate.day); // Izlaz: 27
Aritmetika s datumima
Za dodavanje ili oduzimanje dana, tjedana, mjeseci ili godina, koristite metode `plus` i `minus`. Ove metode vraćaju novi `Temporal.PlainDate` objekt:
const nextWeek = plainDate.plus({ days: 7 });
console.log(nextWeek.toString()); // Izlaz: 2024-11-03
const lastMonth = plainDate.minus({ months: 1 });
console.log(lastMonth.toString()); // Izlaz: 2024-09-27
Uspoređivanje datuma
Možete uspoređivati datume pomoću metode `compare`:
const date1 = new Temporal.PlainDate(2024, 10, 27);
const date2 = new Temporal.PlainDate(2024, 11, 15);
console.log(Temporal.PlainDate.compare(date1, date2)); // Izlaz: -1 (date1 je raniji od date2)
Rad s vremenom
Kreiranje `Temporal.PlainTime` objekta
Da biste kreirali `Temporal.PlainTime`, koristite konstruktor:
const plainTime = new Temporal.PlainTime(10, 30, 0); // Sat, Minuta, Sekunda
console.log(plainTime.toString()); // Izlaz: 10:30:00
Ili koristite metodu `from` s ISO 8601 stringom za vrijeme:
const plainTimeFromString = Temporal.PlainTime.from('10:30:00');
console.log(plainTimeFromString.toString()); // Izlaz: 10:30:00
Dohvaćanje komponenti vremena
console.log(plainTime.hour); // Izlaz: 10
console.log(plainTime.minute); // Izlaz: 30
console.log(plainTime.second); // Izlaz: 0
Aritmetika s vremenom
const later = plainTime.plus({ minutes: 15 });
console.log(later.toString()); // Izlaz: 10:45:00
Zajednički rad s datumom i vremenom
Kreiranje `Temporal.PlainDateTime` objekta
Možete kreirati `Temporal.PlainDateTime` izravno ili kombiniranjem `Temporal.PlainDate` i `Temporal.PlainTime`:
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
console.log(plainDateTime.toString()); // Izlaz: 2024-10-27T10:30:00
const date = new Temporal.PlainDate(2024, 10, 27);
const time = new Temporal.PlainTime(10, 30, 0);
const combinedDateTime = date.toPlainDateTime(time);
console.log(combinedDateTime.toString()); // Izlaz: 2024-10-27T10:30:00
Vremenske zone
Ispravno rukovanje vremenskim zonama ključno je za aplikacije koje se bave korisnicima na različitim lokacijama. Temporal API pruža robusnu podršku za vremenske zone putem `Temporal.ZonedDateTime` i `Temporal.TimeZone` objekata.
Kreiranje `Temporal.ZonedDateTime` objekta
Za kreiranje `Temporal.ZonedDateTime` objekta, potreban vam je `Temporal.PlainDateTime` i identifikator vremenske zone. Identifikatori vremenskih zona temelje se na IANA bazi podataka vremenskih zona (npr. `America/Los_Angeles`, `Europe/London`, `Asia/Tokyo`).
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
console.log(zonedDateTime.toString()); // Izlaz: 2024-10-27T10:30:00-07:00[America/Los_Angeles] (Odstupanje će ovisiti o pravilima ljetnog računanja vremena)
Alternativno, kreirajte `Temporal.ZonedDateTime` iz `Instant` objekta.
const instant = Temporal.Instant.fromEpochSeconds(1666866600); // Primjer vremenske oznake
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO(timeZone); // Vremenska zona poput 'America/Los_Angeles'
console.log(zonedDateTimeFromInstant.toString());
Pretvaranje između vremenskih zona
Možete pretvoriti `Temporal.ZonedDateTime` u drugu vremensku zonu pomoću metode `withTimeZone`:
const newTimeZone = 'Europe/London';
const zonedDateTimeInLondon = zonedDateTime.withTimeZone(newTimeZone);
console.log(zonedDateTimeInLondon.toString()); // Izlaz: 2024-10-27T18:30:00+01:00[Europe/London]
Rad s odstupanjima vremenskih zona
Metoda `getOffsetStringFor` objekta `Temporal.TimeZone` pruža string odstupanja za zadani `Temporal.Instant`:
const timeZoneObject = new Temporal.TimeZone(timeZone);
const offsetString = timeZoneObject.getOffsetStringFor(zonedDateTime.toInstant());
console.log(offsetString); // Izlaz: -07:00 (Ovisno o pravilima ljetnog računanja vremena)
Ključno je koristiti ispravne IANA identifikatore vremenskih zona za točne izračune. Ovi identifikatori se redovito održavaju i ažuriraju kako bi odražavali promjene u ljetnom računanju vremena i granicama vremenskih zona.
Trajanja (Durations)
Objekt `Temporal.Duration` predstavlja vremenski raspon. Može se koristiti za dodavanje ili oduzimanje od datuma i vremena.
Kreiranje `Temporal.Duration` objekta
Možete kreirati `Temporal.Duration` pomoću konstruktora, navodeći godine, mjesece, dane, sate, minute, sekunde, milisekunde, mikrosekunde i nanosekunde:
const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9); // Godine, Mjeseci, Dani, Sati, Minute, Sekunde, Milisekunde, Mikrosekunde, Nanosekunde
console.log(duration.toString()); // Izlaz: P1Y2M3DT4H5M6.007008009S
Ili korištenjem ISO 8601 stringa za trajanje:
const durationFromString = Temporal.Duration.from('P1Y2M3DT4H5M6S');
console.log(durationFromString.toString()); // Izlaz: P1Y2M3DT4H5M6S
Dodavanje trajanja datumima i vremenima
const plainDate = new Temporal.PlainDate(2024, 10, 27);
const duration = new Temporal.Duration(0, 0, 7); // 7 dana
const newDate = plainDate.plus(duration);
console.log(newDate.toString()); // Izlaz: 2024-11-03
Imajte na umu da dodavanje trajanja koja uključuju mjesece ili godine datumima zahtijeva pažljivo razmatranje, jer broj dana u mjesecu ili godini može varirati.
Kalendarski sustavi
Temporal API podržava različite kalendarske sustave osim gregorijanskog kalendara. To je ključno za aplikacije koje trebaju rukovati datumima u različitim kulturnim kontekstima. Iako se podrška još uvijek razvija, ona pruža temelj za buduće proširenje.
Korištenje alternativnih kalendara
Da biste koristili određeni kalendar, možete ga navesti prilikom kreiranja Temporal objekata:
const hebrewDate = new Temporal.PlainDate(5785, 1, 1, { calendar: 'hebrew' });
console.log(hebrewDate.toString()); // Specifičan izlaz može varirati ovisno o implementaciji i formatiranju. U trenutku pisanja, zahtijeva polyfill u mnogim okruženjima.
Važno: Podrška za ne-gregorijanske kalendare može zahtijevati polyfillove ili specifičnu podršku preglednika/okruženja. Provjerite najnovije informacije u dokumentaciji Temporal API-ja i tablicama kompatibilnosti preglednika.
Formatiranje datuma i vremena
Iako se Temporal API fokusira na manipulaciju datumom i vremenom, formatiranje se obično obavlja pomoću `Intl.DateTimeFormat` objekta, koji je dio Internationalization API-ja. Temporal objekti besprijekorno rade s `Intl.DateTimeFormat`.
Korištenje `Intl.DateTimeFormat`
Evo kako formatirati `Temporal.PlainDate` pomoću `Intl.DateTimeFormat`:
const plainDate = new Temporal.PlainDate(2024, 10, 27);
const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatter.format(plainDate)); // Izlaz: October 27, 2024
const formatterGerman = new Intl.DateTimeFormat('de-DE', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatterGerman.format(plainDate)); // Izlaz: 27. Oktober 2024
Možete prilagoditi opcije formata prema svojim potrebama. Prvi argument za `Intl.DateTimeFormat` je lokalizacija (locale), koja određuje jezik i regionalne konvencije koje se koriste za formatiranje. Korištenje različitih lokalizacija (npr. 'en-US', 'de-DE', 'fr-FR', 'ja-JP') proizvodi različite izlazne formate.
Formatiranje `Temporal.ZonedDateTime`
Formatiranje `Temporal.ZonedDateTime` je slično, ali također možete uključiti informacije o vremenskoj zoni u izlaz:
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' });
console.log(formatter.format(zonedDateTime)); // Izlaz: October 27, 2024, 10:30 AM PDT (Skraćenica vremenske zone ovisi o pravilima ljetnog računanja vremena)
Najbolje prakse za internacionalizaciju
Kada radite s datumima i vremenima u globalnom kontekstu, imajte na umu sljedeće najbolje prakse:
- Koristite IANA identifikatore vremenskih zona: Uvijek koristite IANA identifikatore vremenskih zona (npr. `America/Los_Angeles`, `Europe/London`) za točno rukovanje vremenskim zonama.
- Budite svjesni ljetnog računanja vremena: Ljetno računanje vremena (DST) može utjecati na odstupanja vremenskih zona. Temporal API automatski upravlja prijelazima na ljetno računanje vremena.
- Koristite `Intl.DateTimeFormat` za formatiranje: Koristite `Intl.DateTimeFormat` objekt za formatiranje datuma i vremena u skladu s lokalizacijom korisnika.
- Razmotrite kalendarske sustave: Ako vaša aplikacija treba podržavati korisnike u različitim kulturnim kontekstima, razmislite o korištenju alternativnih kalendarskih sustava.
- Pohranjujte datume i vremena u UTC-u: Prilikom pohranjivanja datuma i vremena u bazi podataka, najbolja je praksa pohraniti ih u UTC (Koordinirano univerzalno vrijeme) kako bi se izbjegli problemi s vremenskim zonama. Zatim ih pretvorite u lokalno vrijeme za prikaz. Temporal pruža metode za pretvorbu u i iz UTC-a.
- Testirajte temeljito: Testirajte svoju aplikaciju s različitim vremenskim zonama, lokalizacijama i kalendarskim sustavima kako biste osigurali da radi ispravno za sve korisnike.
Usporedba Temporal API-ja s naslijeđenim Date objektom
Evo tablice koja ističe ključne razlike i prednosti Temporal API-ja u usporedbi s naslijeđenim `Date` objektom:
Značajka | Naslijeđeni `Date` objekt | Temporal API |
---|---|---|
Promjenjivost (Mutability) | Promjenjiv (mijenja originalni objekt) | Nepromjenjiv (vraća nove objekte) |
Podrška za vremenske zone | Ograničena i često problematična | Robusna i točna, temeljena na IANA bazi podataka vremenskih zona |
API | Nedosljedan i težak za korištenje | Jasan, dosljedan i intuitivan |
Preciznost | Milisekunda | Nanosekunda |
Kalendarski sustavi | Ograničen na gregorijanski | Podržava alternativne kalendarske sustave (s podrškom koja se razvija) |
Internacionalizacija | Zahtijeva vanjske biblioteke za robusnu internacionalizaciju | Ugrađena podrška i besprijekorna integracija s `Intl.DateTimeFormat` |
Podrška preglednika i Polyfillovi
Budući da je Temporal API relativno nov, podrška preglednika za njega se još uvijek razvija. Provjerite najnovije tablice kompatibilnosti preglednika (npr. na MDN Web Docs) da biste vidjeli koji preglednici i okruženja ga nativno podržavaju. Za starije preglednike ili okruženja bez nativne podrške, možete koristiti polyfillove kako biste osigurali funkcionalnost Temporal API-ja. Potražite "Temporal API polyfill" na webu kako biste pronašli odgovarajuće opcije.
Zaključak
JavaScript Temporal API predstavlja značajan korak naprijed u rukovanju datumima i vremenima u JavaScriptu. Njegova nepromjenjivost, jasan API, robusna podrška za vremenske zone i mogućnosti kalendarskih sustava čine ga moćnim alatom za programere koji grade aplikacije koje trebaju raditi s datumima i vremenima točno i pouzdano u različitim međunarodnim kontekstima. Iako se podrška preglednika još uvijek razvija, prednosti Temporal API-ja čine ga vrijednim učenja i usvajanja za nove projekte. Prihvaćanjem Temporal API-ja i slijeđenjem najboljih praksi za internacionalizaciju, možete stvoriti aplikacije koje pružaju besprijekorno i točno iskustvo s datumima i vremenima za korisnike diljem svijeta.