Hrvatski

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:

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

Uobičajene zamke

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:

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.