Slovenčina

Komplexný sprievodca používaním Temporal API v JavaScripte pre presné a intuitívne výpočty časových intervalov, pokrývajúci všetko od základného vytvárania trvania až po pokročilú aritmetiku a formátovanie.

JavaScript Temporal Duration: Zvládnutie výpočtov časových intervalov

Temporal API v JavaScripte predstavuje moderný a výkonný spôsob práce s dátumami, časmi a časovými intervalmi. Objekt Temporal.Duration reprezentuje dĺžku času a poskytuje jasný a intuitívny prístup k vykonávaniu výpočtov s časovými intervalmi. Tento článok sa podrobne venuje objektu Temporal.Duration a ukazuje, ako vytvárať, manipulovať a formátovať trvania pre rôzne prípady použitia.

Čo je Temporal.Duration?

Temporal.Duration predstavuje časové rozpätie, vyjadrené v rokoch, mesiacoch, dňoch, hodinách, minútach, sekundách a zlomkoch sekundy (milisekundy, mikrosekundy, nanosekundy). Na rozdiel od objektov Date, ktoré predstavujú konkrétny bod v čase, Temporal.Duration predstavuje množstvo času. Dodržiava formát trvania ISO 8601 (napr. P1Y2M10DT2H30M predstavuje 1 rok, 2 mesiace, 10 dní, 2 hodiny a 30 minút). Temporal API je navrhnuté tak, aby bolo intuitívnejšie a menej náchylné na chyby ako zastaraný objekt Date.

Vytváranie objektov Temporal.Duration

Existuje niekoľko spôsobov, ako vytvoriť objekty Temporal.Duration:

1. Z jednoduchého objektu

Trvanie môžete vytvoriť odovzdaním objektu s požadovanými vlastnosťami:

const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Výstup: P1Y2M10DT2H30M

Týmto sa vytvorí trvanie 1 rok, 2 mesiace, 10 dní, 2 hodiny a 30 minút. Všimnite si, že argumenty zodpovedajú nasledujúcemu poradiu: roky, mesiace, týždne, dni, hodiny, minúty, sekundy, milisekundy, mikrosekundy, nanosekundy.

2. Z reťazca ISO 8601

Trvanie môžete vytvoriť aj z reťazca trvania vo formáte ISO 8601 pomocou Temporal.Duration.from():

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Výstup: P1Y2M10DT2H30M

Toto je obzvlášť užitočné pri práci s trvaniami uloženými vo formáte reťazca alebo prijatými z externého zdroja.

3. Použitie metód add() a subtract() s Temporal.Instant, Temporal.ZonedDateTime atď.

Keď pripočítate alebo odčítate Temporal.Duration od iných typov Temporal (ako Temporal.Instant alebo Temporal.ZonedDateTime), vráti sa Temporal.Duration, ktorý predstavuje rozdiel medzi dvoma bodmi v čase, ak ich potom odčítate. Napríklad:

const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // Výstup: PT5H

Prístup k zložkám trvania

K jednotlivým zložkám objektu Temporal.Duration môžete pristupovať pomocou jeho vlastností:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years);      // Výstup: 1
console.log(duration.months);     // Výstup: 2
console.log(duration.days);       // Výstup: 10
console.log(duration.hours);      // Výstup: 2
console.log(duration.minutes);     // Výstup: 30
console.log(duration.seconds);     // Výstup: 0
console.log(duration.milliseconds); // Výstup: 0
console.log(duration.microseconds); // Výstup: 0
console.log(duration.nanoseconds);  // Výstup: 0

Vykonávanie aritmetických operácií s trvaniami

Objekty Temporal.Duration podporujú sčítanie a odčítanie pomocou metód add() a subtract(). Tieto metódy vracajú nový objekt Temporal.Duration, ktorý predstavuje výsledok operácie.

const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");

const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Výstup: P1Y5M4D

const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Výstup: P10M26D

Tieto metódy môžete tiež reťaziť pre zložitejšie výpočty:

const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // Výstup: P1DT11H30M

Metóda negated() vráti nový objekt Temporal.Duration so všetkými zložkami negovanými:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Výstup: -P1Y2M10DT2H30M

Metóda abs() vráti nový objekt Temporal.Duration so všetkými zložkami ako kladnými hodnotami (absolútne hodnoty):

const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Výstup: P1Y2M10DT2H30M

Metóda with() vám umožňuje vytvoriť novú inštanciu Temporal.Duration s niektorými alebo všetkými vlastnosťami zmenenými na nové hodnoty. Ak hodnota nie je špecifikovaná v objekte argumentu, potom sa použije pôvodná hodnota trvania. Napríklad:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // Výstup: P2Y2M5DT2H30M

Normalizácia trvaní

Trvania môžu byť niekedy vyjadrené v nenormalizovanej forme (napr. P1Y12M, čo by sa dalo zjednodušiť na P2Y). Metóda normalized() sa pokúša zjednodušiť trvanie na jeho najkompaktnejšiu formu. Vyžaduje si však referenčný dátum na zvládnutie zložitosti rôznych dĺžok mesiacov. Na správnu normalizáciu budete potrebovať inštanciu Temporal.PlainDate, Temporal.ZonedDateTime alebo Temporal.Instant.

Napríklad normalizácia trvania zahŕňajúceho mesiace a dni vyžaduje referenčný dátum:

const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // Výstup: P2M1D

V tomto príklade je trvanie P1M32D normalizované vzhľadom na 1. január 2024, čoho výsledkom je P2M1D, pretože január má 31 dní.

Ak pracujete len s časovými zložkami (hodiny, minúty, sekundy atď.), môžete normalizovať bez referenčného dátumu:

const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //alebo vynechajte argument relativeTo
console.log(normalizedDuration.toString()); // Výstup: P1DT2H1M

Porovnávanie trvaní

Trvania môžete porovnávať pomocou metódy compare(). Táto metóda vráti:

const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");

const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Výstup: 1

Praktické príklady

1. Výpočet času do udalosti

Predpokladajme, že chcete vypočítať zostávajúci čas do konkrétnej udalosti. Použitím Temporal.Now.zonedDateTimeISO() získate aktuálny čas a odčítate dátum udalosti. Ak dátum udalosti už uplynul, výsledok bude záporný.

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()); // Výstup: napr., P262DT14H30M (v závislosti od aktuálneho dátumu a času)

2. Sledovanie trvania projektových úloh

V projektovom manažmente môžete použiť Temporal.Duration na sledovanie odhadovaného alebo skutočného trvania úloh.

const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // 8 hodín
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // 16 hodín

const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Celkové odhadované trvanie: ${totalEstimatedDuration.toString()}`); // Výstup: Celkové odhadované trvanie: P1DT

3. Výpočet veku

Hoci presný výpočet veku vyžaduje zohľadnenie priestupných rokov a časových pásiem, Temporal.Duration môže poskytnúť primeraný odhad:

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(`Odhadovaný vek: ${ageDuration.years} rokov`); // Výstup: Odhadovaný vek: 33 rokov

4. Zobrazenie trvaní v čitateľnej forme

Často potrebujete zobraziť trvania v ľudsky čitateľnom formáte. Hoci Temporal.Duration nemá vstavané funkcie na formátovanie, môžete si vytvoriť vlastnú logiku formátovania:

function formatDuration(duration) {
  const parts = [];
  if (duration.years) parts.push(`${duration.years} year${duration.years > 1 ? 's' : ''}`);
  if (duration.months) parts.push(`${duration.months} month${duration.months > 1 ? 's' : ''}`);
  if (duration.days) parts.push(`${duration.days} day${duration.days > 1 ? 's' : ''}`);
  if (duration.hours) parts.push(`${duration.hours} hour${duration.hours > 1 ? 's' : ''}`);
  if (duration.minutes) parts.push(`${duration.minutes} minute${duration.minutes > 1 ? 's' : ''}`);
  if (duration.seconds) parts.push(`${duration.seconds} second${duration.seconds > 1 ? 's' : ''}`);

  return parts.join(', ');
}

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // Výstup: 1 rok, 2 mesiace, 10 dní, 2 hodiny, 30 minút

Pokročilé použitie a dôležité aspekty

1. Spracovanie časových pásiem

Pri práci s časovými intervalmi, ktoré prekračujú hranice časových pásiem alebo prechody na letný čas, je kľúčové použiť Temporal.ZonedDateTime na zabezpečenie presných výpočtov. Použitie Temporal.PlainDate a Temporal.PlainTime sa vyhne akýmkoľvek konverziám časových pásiem.

2. Najmenšia jednotka a zaokrúhľovanie

Metódy `since()` a `until()` často prijímajú možnosti na definovanie najmenšej jednotky pre výsledné trvanie. Napríklad výpočet času *do* udalosti a obmedzenie výsledkov na dni.

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()); //príklad výstupu PT340D

3. Priestupné sekundy

Temporal natívne nezohľadňuje priestupné sekundy. Ak vyžadujete extrémnu presnosť, budete musieť priestupné sekundy spracovať samostatne.

4. Časové pásma IANA

Temporal API sa spolieha na databázu časových pásiem IANA (Internet Assigned Numbers Authority). Uistite sa, že vaše prostredie má aktuálnu verziu databázy IANA na presné spracovanie konverzií časových pásiem.

Osvedčené postupy

Bežné úskalia

Prípady použitia v reálnom svete naprieč rôznymi kultúrami

Temporal API môže byť obzvlášť prínosné v globálnych aplikáciách, kde sú rozdiely v časových pásmach a kultúrne nuansy významné. Tu je niekoľko príkladov:

Záver

Temporal.Duration poskytuje robustný a intuitívny spôsob práce s časovými intervalmi v JavaScripte. Porozumením jeho funkciám a osvedčeným postupom môžete vo svojich aplikáciách s istotou vykonávať presné a spoľahlivé výpočty trvania. Prijatie Temporal API vedie k čistejšiemu, udržateľnejšiemu kódu a znižuje riziko chýb spojených so zastaraným spracovaním dátumu a času.

Keď sa budete hlbšie ponárať do Temporal API, nezabudnite nahliadnuť do oficiálnej dokumentácie a experimentovať s rôznymi scenármi, aby ste plne pochopili jeho schopnosti. Svojím moderným dizajnom a komplexnými funkciami je Temporal pripravený zmeniť spôsob, akým v JavaScripte pracujeme s dátumami, časmi a trvaniami.