Română

Un ghid complet pentru utilizarea API-ului Temporal din JavaScript pentru calcule precise și intuitive ale intervalelor de timp, acoperind totul de la crearea duratelor de bază la aritmetică și formatare avansată.

Durata Temporală JavaScript: Stăpânirea Calculelor de Interval de Timp

API-ul Temporal din JavaScript introduce o modalitate modernă și puternică de a gestiona datele, orele și intervalele de timp. Obiectul Temporal.Duration reprezintă o perioadă de timp, oferind o abordare clară și intuitivă pentru efectuarea calculelor cu intervale de timp. Acest articol explorează detaliile Temporal.Duration, demonstrând cum să creați, manipulați și formatați durate pentru diverse cazuri de utilizare.

Ce este Temporal.Duration?

Temporal.Duration reprezintă o întindere de timp, exprimată în ani, luni, zile, ore, minute, secunde și fracțiuni de secundă (milisecunde, microsecunde, nanosecunde). Spre deosebire de obiectele Date care reprezintă un punct specific în timp, Temporal.Duration reprezintă o cantitate de timp. Acesta respectă formatul de durată ISO 8601 (de ex., P1Y2M10DT2H30M reprezintă 1 an, 2 luni, 10 zile, 2 ore și 30 de minute). API-ul Temporal este conceput pentru a fi mai intuitiv și mai puțin predispus la erori decât vechiul obiect Date.

Crearea Obiectelor Temporal.Duration

Există mai multe moduri de a crea obiecte Temporal.Duration:

1. Dintr-un Obiect Simplu

Puteți crea o durată transmițând un obiect cu proprietățile dorite:

const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Ieșire: P1Y2M10DT2H30M

Aceasta creează o durată de 1 an, 2 luni, 10 zile, 2 ore și 30 de minute. Rețineți că argumentele corespund următoarei ordini: years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds.

2. Dintr-un Șir de Caractere ISO 8601

Puteți crea, de asemenea, o durată dintr-un șir de caractere de durată ISO 8601 folosind Temporal.Duration.from():

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Ieșire: P1Y2M10DT2H30M

Acest lucru este deosebit de util atunci când lucrați cu durate stocate în format de șir de caractere sau primite de la o sursă externă.

3. Folosind metodele add() și subtract() cu Temporal.Instant, Temporal.ZonedDateTime, etc.

Când adăugați sau scădeți Temporal.Duration din alte tipuri Temporal (cum ar fi Temporal.Instant sau Temporal.ZonedDateTime), un Temporal.Duration este returnat reprezentând diferența dintre cele două puncte în timp dacă le scădeți ulterior. De exemplu:

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

Accesarea Componentelor Duratei

Puteți accesa componentele individuale ale unui obiect Temporal.Duration folosind proprietățile sale:

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

Efectuarea de Calcule Aritmetice cu Durate

Obiectele Temporal.Duration suportă adunarea și scăderea folosind metodele add() și subtract(). Aceste metode returnează un nou obiect Temporal.Duration care reprezintă rezultatul operației.

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

const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Ieșire: P1Y5M4D

const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Ieșire: P10M26D

Puteți, de asemenea, înlănțui aceste metode pentru calcule mai complexe:

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

Metoda negated() returnează un nou obiect Temporal.Duration cu toate componentele negate:

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Ieșire: -P1Y2M10DT2H30M

Metoda abs() returnează un nou obiect Temporal.Duration cu toate componentele ca valori pozitive (valori absolute):

const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Ieșire: P1Y2M10DT2H30M

Metoda with() vă permite să creați o nouă instanță Temporal.Duration cu unele sau toate proprietățile modificate la valori noi. Dacă o valoare nu este specificată în obiectul argument, atunci va fi utilizată valoarea originală a duratei. De exemplu:

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

Normalizarea Duratelor

Duratele pot fi uneori exprimate într-o formă nenormalizată (de ex., P1Y12M, care ar putea fi simplificat la P2Y). Metoda normalized() încearcă să simplifice o durată la forma sa cea mai compactă. Cu toate acestea, necesită o dată de referință pentru a gestiona complexitățile lungimilor variabile ale lunilor. Pentru a normaliza corect, veți avea nevoie de o instanță Temporal.PlainDate, Temporal.ZonedDateTime sau Temporal.Instant.

De exemplu, normalizarea unei durate care implică luni și zile necesită o dată de referință:

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

În acest exemplu, durata P1M32D este normalizată în raport cu 1 ianuarie 2024, rezultând în P2M1D deoarece ianuarie are 31 de zile.

Dacă lucrați doar cu componente de timp (ore, minute, secunde etc.), puteți normaliza fără o dată de referință:

const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //sau omiteți argumentul relativeTo
console.log(normalizedDuration.toString()); // Ieșire: P1DT2H1M

Compararea Duratelor

Puteți compara duratele folosind metoda compare(). Această metodă returnează:

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

const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Ieșire: 1

Exemple Practice

1. Calcularea Timpului Până la un Eveniment

Să presupunem că doriți să calculați timpul rămas până la un eveniment specific. Folosind Temporal.Now.zonedDateTimeISO() pentru a obține ora curentă și scăzând data evenimentului. Dacă data evenimentului a trecut, rezultatul va fi negativ.

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()); // Ieșire: ex., P262DT14H30M (în funcție de data și ora curente)

2. Urmărirea Duratelor Sarcinilor de Proiect

În managementul de proiect, puteți utiliza Temporal.Duration pentru a urmări durata estimată sau reală a sarcinilor.

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

const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Durata totală estimată: ${totalEstimatedDuration.toString()}`); // Ieșire: Durata totală estimată: P1DT

3. Calcularea Vârstei

Deși calcularea exactă a vârstei necesită luarea în considerare a anilor bisecți și a fusurilor orare, Temporal.Duration poate oferi o estimare rezonabilă:

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(`Vârsta estimată: ${ageDuration.years} ani`); // Ieșire: Vârsta estimată: 33 ani

4. Afișarea Duratelor Lizibile pentru Oameni

Adesea, trebuie să afișați duratele într-un format lizibil pentru oameni. Deși Temporal.Duration nu are funcții de formatare încorporate, puteți crea o logică de formatare personalizată:

function formatDuration(duration) {
  const parts = [];
  if (duration.years) parts.push(`${duration.years} an${duration.years > 1 ? 'i' : ''}`);
  if (duration.months) parts.push(`${duration.months} lun${duration.months > 1 ? 'i' : 'ă'}`);
  if (duration.days) parts.push(`${duration.days} zi${duration.days > 1 ? 'le' : ''}`);
  if (duration.hours) parts.push(`${duration.hours} or${duration.hours > 1 ? 'e' : 'ă'}`);
  if (duration.minutes) parts.push(`${duration.minutes} minut${duration.minutes > 1 ? 'e' : ''}`);
  if (duration.seconds) parts.push(`${duration.seconds} secund${duration.seconds > 1 ? 'e' : 'ă'}`);

  return parts.join(', ');
}

const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // Ieșire: 1 an, 2 luni, 10 zile, 2 ore, 30 minute

Utilizare Avansată și Considerații

1. Gestionarea Fusurilor Orare

Când lucrați cu intervale de timp care trec peste limitele fusurilor orare sau tranzițiile la ora de vară, este crucial să utilizați Temporal.ZonedDateTime pentru a asigura calcule exacte. Utilizarea Temporal.PlainDate și Temporal.PlainTime va evita orice conversie de fus orar.

2. Cea Mai Mică Unitate și Rotunjirea

Metodele `since()` și `until()` acceptă adesea opțiuni pentru a defini cea mai mică unitate pentru durata rezultată. De exemplu, calcularea timpului *până la* un eveniment și limitarea rezultatelor la zile.

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()); //exemplu de ieșire PT340D

3. Secunde Bisecte

Temporal nu ia în considerare secundele bisecte în mod nativ. Dacă aveți nevoie de o precizie extremă, va trebui să gestionați secundele bisecte separat.

4. Fusuri Orare IANA

API-ul Temporal se bazează pe baza de date a fusurilor orare IANA (Internet Assigned Numbers Authority). Asigurați-vă că mediul dvs. are o versiune actualizată a bazei de date IANA pentru a gestiona corect conversiile de fus orar.

Cele Mai Bune Practici

Capcane Comune

Cazuri de Utilizare Reale în Diverse Culturi

API-ul Temporal poate fi deosebit de benefic în aplicațiile globale unde diferențele de fus orar și nuanțele culturale sunt semnificative. Iată câteva exemple:

Concluzie

Temporal.Duration oferă o modalitate robustă și intuitivă de a lucra cu intervale de timp în JavaScript. Înțelegând caracteristicile și cele mai bune practici ale sale, puteți efectua cu încredere calcule de durată exacte și fiabile în aplicațiile dvs. Adoptarea API-ului Temporal duce la un cod mai curat, mai ușor de întreținut și reduce riscul de erori asociate cu gestionarea veche a datei și orei.

Pe măsură ce aprofundați API-ul Temporal, nu uitați să consultați documentația oficială și să experimentați cu diferite scenarii pentru a înțelege pe deplin capabilitățile sale. Cu designul său modern și caracteristicile cuprinzătoare, Temporal este pregătit să revoluționeze modul în care gestionăm datele, orele și duratele în JavaScript.