Sveobuhvatan vodič za korištenje JavaScriptovog Temporal API-ja za precizne i intuitivne izračune vremenskih intervala, od stvaranja trajanja do napredne aritmetike i formatiranja.
JavaScript Temporal trajanje: Ovladavanje izračunima vremenskih intervala
JavaScriptov Temporal API uvodi moderan i moćan način rukovanja datumima, vremenima i vremenskim intervalima. Objekt Temporal.Duration
predstavlja duljinu vremena, pružajući jasan i intuitivan pristup izvođenju izračuna s vremenskim intervalima. Ovaj članak detaljno opisuje Temporal.Duration
, demonstrirajući kako stvoriti, manipulirati i formatirati trajanja za različite slučajeve upotrebe.
Što je Temporal.Duration?
Temporal.Duration
predstavlja vremenski raspon, izražavajući ga u smislu godina, mjeseci, dana, sati, minuta, sekundi i dijelova sekunde (milisekundi, mikrosekundi, nanosekundi). Za razliku od objekata Date
koji predstavljaju određenu točku u vremenu, Temporal.Duration
predstavlja količinu vremena. Pridržava se formata trajanja ISO 8601 (npr., P1Y2M10DT2H30M
predstavlja 1 godinu, 2 mjeseca, 10 dana, 2 sata i 30 minuta). Temporal API dizajniran je da bude intuitivniji i manje sklon pogreškama od naslijeđenog objekta Date
.
Stvaranje objekata Temporal.Duration
Postoji nekoliko načina za stvaranje objekata Temporal.Duration
:
1. Iz običnog objekta
Možete stvoriti trajanje prosljeđivanjem objekta s željenim svojstvima:
const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Izlaz: P1Y2M10DT2H30M
Ovo stvara trajanje od 1 godine, 2 mjeseca, 10 dana, 2 sata i 30 minuta. Imajte na umu da argumenti odgovaraju sljedećem redoslijedu: years
, months
, weeks
, days
, hours
, minutes
, seconds
, milliseconds
, microseconds
, nanoseconds
.
2. Iz ISO 8601 niza
Također možete stvoriti trajanje iz ISO 8601 niza trajanja koristeći Temporal.Duration.from()
:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Izlaz: P1Y2M10DT2H30M
To je posebno korisno kada se radi s trajanjima pohranjenim u formatu niza ili primljenim iz vanjskog izvora.
3. Korištenje metoda add()
i subtract()
s Temporal.Instant
, Temporal.ZonedDateTime
, itd.
Kada dodajete ili oduzimate Temporal.Duration
od drugih Temporal tipova (poput Temporal.Instant
ili Temporal.ZonedDateTime
), vraća se Temporal.Duration
koji predstavlja razliku između dvije točke u vremenu ako ih zatim oduzmete. Na primjer:
const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // Izlaz: PT5H
Pristup komponentama trajanja
Možete pristupiti pojedinačnim komponentama objekta Temporal.Duration
pomoću njegovih svojstava:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years); // Izlaz: 1
console.log(duration.months); // Izlaz: 2
console.log(duration.days); // Izlaz: 10
console.log(duration.hours); // Izlaz: 2
console.log(duration.minutes); // Izlaz: 30
console.log(duration.seconds); // Izlaz: 0
console.log(duration.milliseconds); // Izlaz: 0
console.log(duration.microseconds); // Izlaz: 0
console.log(duration.nanoseconds); // Izlaz: 0
Izvođenje aritmetike s trajanjima
Objekti Temporal.Duration
podržavaju zbrajanje i oduzimanje pomoću metoda add()
i subtract()
. Ove metode vraćaju novi objekt Temporal.Duration
koji predstavlja rezultat operacije.
const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");
const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Izlaz: P1Y5M4D
const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Izlaz: P10M26D
Također možete povezati ove metode za složenije izračune:
const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // Izlaz: P1DT11H30M
Metoda negated()
vraća novi objekt Temporal.Duration
sa svim komponentama negiranim:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Izlaz: -P1Y2M10DT2H30M
Metoda abs()
vraća novi objekt Temporal.Duration
sa svim komponentama kao pozitivnim vrijednostima (apsolutnim vrijednostima):
const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Izlaz: P1Y2M10DT2H30M
Metoda with()
omogućuje vam stvaranje nove instance Temporal.Duration
s nekim ili svim svojstvima promijenjenim u nove vrijednosti. Ako vrijednost nije navedena u argumentnom objektu, tada će se koristiti izvorna vrijednost trajanja. Na primjer:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // Izlaz: P2Y2M5DT2H30M
Normaliziranje trajanja
Trajanja se ponekad mogu izraziti u nenormaliziranom obliku (npr. P1Y12M
, što bi se moglo pojednostaviti na P2Y
). Metoda normalized()
pokušava pojednostaviti trajanje u njegov najkompaktniji oblik. Međutim, zahtijeva referentni datum za rješavanje složenosti različitih duljina mjeseci. Da biste ispravno normalizirali, trebat će vam instanca Temporal.PlainDate
, Temporal.ZonedDateTime
ili Temporal.Instant
.
Na primjer, normaliziranje trajanja koje uključuje mjesece i dane zahtijeva referentni datum:
const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // Izlaz: P2M1D
U ovom primjeru, trajanje P1M32D
je normalizirano u odnosu na 1. siječnja 2024., što rezultira s P2M1D
jer siječanj ima 31 dan.
Ako se samo bavite vremenskim komponentama (sati, minute, sekunde, itd.), možete normalizirati bez referentnog datuma:
const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //ili izostavite argument relativeTo
console.log(normalizedDuration.toString()); // Izlaz: P1DT2H1M
Uspoređivanje trajanja
Možete usporediti trajanja pomoću metode compare()
. Ova metoda vraća:
- -1 ako je prvo trajanje kraće od drugog trajanja.
- 0 ako su trajanja jednaka.
- 1 ako je prvo trajanje dulje od drugog trajanja.
const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");
const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Izlaz: 1
Praktični primjeri
1. Izračunavanje vremena do događaja
Pretpostavimo da želite izračunati preostalo vrijeme do određenog događaja. Korištenjem Temporal.Now.zonedDateTimeISO()
za dobivanje trenutnog vremena i oduzimanjem datuma događaja. Ako je datum događaja prošao, izlaz će biti negativan.
const eventDate = Temporal.ZonedDateTime.from({ timeZone: 'America/Los_Angeles', year: 2024, month: 12, day: 25, hour: 9, minute: 0, second: 0 });
const now = Temporal.Now.zonedDateTimeISO('America/Los_Angeles');
const durationUntilEvent = eventDate.since(now);
console.log(durationUntilEvent.toString()); // Izlaz: npr., P262DT14H30M (ovisno o trenutnom datumu i vremenu)
2. Praćenje trajanja zadataka projekta
U upravljanju projektima možete koristiti Temporal.Duration
za praćenje procijenjenog ili stvarnog trajanja zadataka.
const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // 8 sati
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // 16 sati
const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Ukupno procijenjeno trajanje: ${totalEstimatedDuration.toString()}`); // Izlaz: Ukupno procijenjeno trajanje: P1DT
3. Izračunavanje dobi
Iako izračunavanje dobi točno zahtijeva razmatranje prijestupnih godina i vremenskih zona, Temporal.Duration
može dati razumnu procjenu:
const birthDate = Temporal.PlainDate.from("1990-05-15");
const currentDate = Temporal.PlainDate.from("2024-01-20");
const ageDuration = currentDate.since(birthDate, { smallestUnit: 'years' });
console.log(`Procijenjena dob: ${ageDuration.years} godina`); // Izlaz: Procijenjena dob: 33 godine
4. Prikaz trajanja čitljivih ljudima
Često trebate prikazati trajanja u formatu čitljivom ljudima. Iako Temporal.Duration
nema ugrađene funkcije formatiranja, možete stvoriti prilagođenu logiku formatiranja:
function formatDuration(duration) {
const parts = [];
if (duration.years) parts.push(`${duration.years} godina${duration.years > 1 ? 'e' : ''}`);
if (duration.months) parts.push(`${duration.months} mjesec${duration.months > 1 ? 'a' : ''}`);
if (duration.days) parts.push(`${duration.days} dan${duration.days > 1 ? 'a' : ''}`);
if (duration.hours) parts.push(`${duration.hours} sat${duration.hours > 1 ? 'a' : ''}`);
if (duration.minutes) parts.push(`${duration.minutes} minuta${duration.minutes > 1 ? 'e' : ''}`);
if (duration.seconds) parts.push(`${duration.seconds} sekunda${duration.seconds > 1 ? 'e' : ''}`);
return parts.join(', ');
}
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // Izlaz: 1 godina, 2 mjeseca, 10 dana, 2 sata, 30 minuta
Napredna upotreba i razmatranja
1. Rukovanje vremenskom zonom
Kada se bavite vremenskim intervalima koji prelaze granice vremenske zone ili prijelaze na ljetno računanje vremena, ključno je koristiti Temporal.ZonedDateTime
kako biste osigurali točne izračune. Korištenje Temporal.PlainDate
i Temporal.PlainTime
izbjeći će sve pretvorbe vremenske zone.
2. Najmanja jedinica i zaokruživanje
Metode `since()` i `until()` često prihvaćaju opcije za definiranje najmanje jedinice za dobiveno trajanje. Na primjer, izračunavanje vremena *do* događaja i ograničavanje rezultata na dane.
const eventDate = Temporal.PlainDate.from("2024-12-25");
const now = Temporal.PlainDate.from("2024-01-20");
const durationUntilEvent = now.until(eventDate, { smallestUnit: 'days' });
console.log(durationUntilEvent.toString()); //primjer izlaza PT340D
3. Prijestupne sekunde
Temporal ne uzima u obzir prijestupne sekunde izvorno. Ako vam je potrebna iznimna preciznost, morat ćete zasebno riješiti prijestupne sekunde.
4. IANA vremenske zone
Temporal API se oslanja na IANA (Internet Assigned Numbers Authority) bazu podataka vremenske zone. Provjerite ima li vaše okruženje ažurnu verziju IANA baze podataka kako biste točno obradili pretvorbe vremenske zone.
Najbolje prakse
- Koristite ISO 8601 format za nizove trajanja: To osigurava dosljednost i interoperabilnost.
- Odaberite odgovarajući Temporal tip: Koristite
Temporal.PlainDate
,Temporal.PlainTime
,Temporal.ZonedDateTime
iliTemporal.Instant
na temelju toga trebate li podršku za vremensku zonu ili ne. - Normalizirajte trajanja kada je potrebno: Normalizacija pojednostavljuje trajanja i olakšava njihovu usporedbu.
- Pažljivo rukujte vremenskim zonama: Pretvorbe vremenske zone mogu biti složene, stoga koristite
Temporal.ZonedDateTime
i budite svjesni prijelaza na ljetno računanje vremena. - Uzmite u obzir najmanju jedinicu: Prilikom izračunavanja trajanja navedite najmanju jedinicu kako biste dobili željenu razinu preciznosti.
- Napišite jedinica testove: Temeljito testirajte svoj kod kako biste osigurali točnost izračuna trajanja.
Uobičajene zamke
- Ignoriranje vremenskih zona: Neuzimanje u obzir vremenskih zona može dovesti do netočnih izračuna trajanja, osobito kada se radi o događajima na različitim lokacijama.
- Korištenje naslijeđenog objekta Date: Naslijeđeni objekt
Date
poznat je po svojim čudnostima i nedosljednostima. Preferirajte Temporal API za pouzdanije rukovanje datumom i vremenom. - Nenormaliziranje trajanja: Nenormaliziranje trajanja može učiniti usporedbe i izračune složenijima.
- Netočan ISO 8601 format: Korištenje nevažećeg niza trajanja ISO 8601 može uzrokovati pogreške.
Primjeri iz stvarnog svijeta u različitim kulturama
Temporal API može biti posebno koristan u globalnim aplikacijama gdje su razlike u vremenskim zonama i kulturne nijanse značajne. Evo nekoliko primjera:
- Globalno zakazivanje događaja: Točno zakazivanje događaja u više vremenskih zona, uzimajući u obzir prijelaze na ljetno računanje vremena. Na primjer, zakazivanje webinara koji počinje u 9:00 PST i prikazivanje odgovarajućeg vremena početka u različitim vremenskim zonama kao što su CET, JST i AEDT.
- Planiranje međunarodnih putovanja: Izračunavanje trajanja putovanja, uključujući stanke i promjene vremenske zone. To je korisno za generiranje itinerara i upravljanje rasporedima letova. Na primjer, izračunavanje ukupnog vremena putovanja od New Yorka do Tokija, uključujući zaustavljanje u Londonu i prilagođavanje razlikama u vremenskim zonama.
- Globalna e-trgovina: Prikazivanje procijenjenih vremena isporuke u korisnikovoj lokalnoj vremenskoj zoni. To zahtijeva razmatranje izvorne vremenske zone, trajanja dostave i odredišne vremenske zone. Na primjer, artikl poslan iz skladišta u Njemačkoj kupcu u Australiji, s procijenjenim vremenom isporuke od 7 dana, prikazan u korisnikovom lokalnom vremenu.
- Prekogranične financijske transakcije: Točno izračunavanje kamatnih stopa ili rokova plaćanja u različitim regijama. To često uključuje razmatranje različitih radnih dana i praznika u svakoj zemlji. Na primjer, izračunavanje kamata na zajam u Singapuru, uzimajući u obzir singapurske državne praznike.
- Multikulturne kalendarske aplikacije: Podrška raznim kalendarskim sustavima, kao što su islamski ili hebrejski kalendar, i točno izračunavanje trajanja događaja i podsjetnika na temelju tih kalendara.
- Globalno upravljanje projektima: Praćenje trajanja i rokova projektnih zadataka u distribuiranom timu, uzimajući u obzir različite rasporede rada i vremenske zone.
Zaključak
Temporal.Duration
pruža robustan i intuitivan način rada s vremenskim intervalima u JavaScriptu. Razumijevanjem njegovih značajki i najboljih praksi, možete pouzdano izvoditi točne i pouzdane izračune trajanja u svojim aplikacijama. Usvajanje Temporal API-ja dovodi do čistijeg, lakšeg održavanja koda i smanjuje rizik od pogrešaka povezanih s naslijeđenim rukovanjem datumom i vremenom.
Dok se udubljujete u Temporal API, ne zaboravite konzultirati službenu dokumentaciju i eksperimentirati s različitim scenarijima kako biste u potpunosti shvatili njegove mogućnosti. Sa svojim modernim dizajnom i sveobuhvatnim značajkama, Temporal bi trebao revolucionirati način na koji rukujemo datumima, vremenima i trajanjima u JavaScriptu.