Išsamus vadovas, kaip naudoti JavaScript Temporal API tiksliam ir intuityviam laiko intervalų skaičiavimui, apimantis viską nuo paprasto trukmės kūrimo iki pažangios aritmetikos ir formatavimo.
JavaScript Temporal Duration: Laiko intervalo skaičiavimų įvaldymas
JavaScript Temporal API pristato modernų ir galingą būdą valdyti datas, laikus ir laiko intervalus. Temporal.Duration
objektas atvaizduoja laiko trukmę, pateikdamas aiškų ir intuityvų būdą atlikti skaičiavimus su laiko intervalais. Šiame straipsnyje gilinamasi į Temporal.Duration
detales, demonstruojant, kaip kurti, manipuliuoti ir formatuoti trukmes įvairiems naudojimo atvejams.
Kas yra Temporal.Duration?
Temporal.Duration
atvaizduoja laiko tarpą, išreikšdamas jį metais, mėnesiais, dienomis, valandomis, minutėmis, sekundėmis ir sekundės dalimis (milisekundėmis, mikrosekundėmis, nanosekundėmis). Skirtingai nuo Date
objektų, kurie atvaizduoja konkretų laiko momentą, Temporal.Duration
atvaizduoja laiko kiekį. Jis atitinka ISO 8601 trukmės formatą (pvz., P1Y2M10DT2H30M
atvaizduoja 1 metus, 2 mėnesius, 10 dienų, 2 valandas ir 30 minučių). Temporal API sukurtas taip, kad būtų intuityvesnis ir mažiau linkęs į klaidas nei senasis Date
objektas.
Temporal.Duration objektų kūrimas
Yra keli būdai sukurti Temporal.Duration
objektus:
1. Iš paprasto objekto
Galite sukurti trukmę perduodami objektą su norimomis savybėmis:
const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Output: P1Y2M10DT2H30M
Tai sukuria 1 metų, 2 mėnesių, 10 dienų, 2 valandų ir 30 minučių trukmę. Atminkite, kad argumentai atitinka šią tvarką: years
, months
, weeks
, days
, hours
, minutes
, seconds
, milliseconds
, microseconds
, nanoseconds
.
2. Iš ISO 8601 eilutės
Taip pat galite sukurti trukmę iš ISO 8601 trukmės eilutės naudodami Temporal.Duration.from()
:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Output: P1Y2M10DT2H30M
Tai ypač naudinga, kai dirbate su trukmėmis, saugomomis eilutės formatu arba gautomis iš išorinio šaltinio.
3. Naudojant add()
ir subtract()
metodus su Temporal.Instant
, Temporal.ZonedDateTime
ir kt.
Kai pridedate arba atimate Temporal.Duration
iš kitų Temporal tipų (pvz., Temporal.Instant
arba Temporal.ZonedDateTime
), grąžinamas Temporal.Duration
, atvaizduojantis skirtumą tarp dviejų laiko momentų, jei juos atimsite. Pavyzdžiui:
const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // Output: PT5H
Prieiga prie trukmės komponentų
Galite pasiekti atskirus Temporal.Duration
objekto komponentus naudodami jo savybes:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years); // Output: 1
console.log(duration.months); // Output: 2
console.log(duration.days); // Output: 10
console.log(duration.hours); // Output: 2
console.log(duration.minutes); // Output: 30
console.log(duration.seconds); // Output: 0
console.log(duration.milliseconds); // Output: 0
console.log(duration.microseconds); // Output: 0
console.log(duration.nanoseconds); // Output: 0
Aritmetikos atlikimas su trukmėmis
Temporal.Duration
objektai palaiko sudėtį ir atimtį naudojant add()
ir subtract()
metodus. Šie metodai grąžina naują Temporal.Duration
objektą, atvaizduojantį operacijos rezultatą.
const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");
const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Output: P1Y5M4D
const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Output: P10M26D
Taip pat galite sujungti šiuos metodus sudėtingesniems skaičiavimams:
const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // Output: P1DT11H30M
negated()
metodas grąžina naują Temporal.Duration
objektą su visais neigiamais komponentais:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Output: -P1Y2M10DT2H30M
abs()
metodas grąžina naują Temporal.Duration
objektą su visais komponentais kaip teigiamomis reikšmėmis (absoliučios vertės):
const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Output: P1Y2M10DT2H30M
with()
metodas leidžia sukurti naują Temporal.Duration
egzempliorių, kurio kai kurios arba visos savybės pakeistos į naujas reikšmes. Jei reikšmė nenurodyta argumento objekte, bus naudojama originali trukmės reikšmė. Pavyzdžiui:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // Output: P2Y2M5DT2H30M
Trukmių normalizavimas
Trukmes kartais gali būti išreikštos nenormalizuota forma (pvz., P1Y12M
, kurią galima supaprastinti iki P2Y
). normalized()
metodas bando supaprastinti trukmę iki kompaktiškiausios formos. Tačiau jam reikia atskaitos datos, kad būtų galima valdyti skirtingų mėnesių ilgių sudėtingumą. Norėdami tinkamai normalizuoti, jums reikės Temporal.PlainDate
, Temporal.ZonedDateTime
arba Temporal.Instant
egzemplioriaus.
Pavyzdžiui, norint normalizuoti trukmę, apimančią mėnesius ir dienas, reikia atskaitos datos:
const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // Output: P2M1D
Šiame pavyzdyje trukmė P1M32D
normalizuojama atsižvelgiant į 2024 m. sausio 1 d., todėl gaunama P2M1D
, nes sausį yra 31 diena.
Jei dirbate tik su laiko komponentais (valandomis, minutėmis, sekundėmis ir kt.), galite normalizuoti be atskaitos datos:
const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //or omit relativeTo argument
console.log(normalizedDuration.toString()); // Output: P1DT2H1M
Trukmių palyginimas
Galite palyginti trukmes naudodami compare()
metodą. Šis metodas grąžina:
- -1, jei pirmoji trukmė yra trumpesnė už antrąją trukmę.
- 0, jei trukmės yra lygios.
- 1, jei pirmoji trukmė yra ilgesnė už antrąją trukmę.
const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");
const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Output: 1
Praktiniai pavyzdžiai
1. Laiko iki įvykio apskaičiavimas
Tarkime, kad norite apskaičiuoti laiką, likusį iki konkretaus įvykio. Naudojant Temporal.Now.zonedDateTimeISO()
, kad gautumėte dabartinį laiką, ir atimant įvykio datą. Jei įvykio data jau praėjo, išvestis bus neigiama.
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()); // Output: e.g., P262DT14H30M (depending on the current date and time)
2. Projekto užduočių trukmės stebėjimas
Projektų valdyme galite naudoti Temporal.Duration
, kad stebėtumėte numatomą arba faktinę užduočių trukmę.
const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // 8 hours
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // 16 hours
const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Total estimated duration: ${totalEstimatedDuration.toString()}`); // Output: Total estimated duration: P1DT
3. Amžiaus apskaičiavimas
Nors tiksliai apskaičiuojant amžių reikia atsižvelgti į keliamuosius metus ir laiko juostas, Temporal.Duration
gali pateikti pagrįstą įvertinimą:
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(`Estimated age: ${ageDuration.years} years`); // Output: Estimated age: 33 years
4. Žmogui suprantamos trukmės rodymas
Dažnai reikia rodyti trukmes žmogui suprantamu formatu. Nors Temporal.Duration
neturi įtaisytų formatavimo funkcijų, galite sukurti pasirinktinę formatavimo logiką:
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); // Output: 1 year, 2 months, 10 days, 2 hours, 30 minutes
Išplėstinis naudojimas ir svarstymai
1. Laiko juostos tvarkymas
Kai dirbate su laiko intervalais, kurie kerta laiko juostų ribas arba vasaros laiko perėjimus, labai svarbu naudoti Temporal.ZonedDateTime
, kad užtikrintumėte tikslius skaičiavimus. Naudojant Temporal.PlainDate
ir Temporal.PlainTime
bus išvengta bet kokių laiko juostos konvertavimų.
2. Mažiausias vienetas ir apvalinimas
Metodai `since()` ir `until()` dažnai priima parinktis, kad apibrėžtų mažiausią vienetą gautai trukmei. Pavyzdžiui, apskaičiuojant laiką *iki* įvykio ir apribojant rezultatus iki dienų.
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()); //example output PT340D
3. Keliosios sekundės
Temporal natūraliai neatsižvelgia į keliamąsias sekundes. Jei jums reikia itin didelio tikslumo, turėsite tvarkyti keliamąsias sekundes atskirai.
4. IANA laiko juostos
Temporal API remiasi IANA (Internet Assigned Numbers Authority) laiko juostų duomenų baze. Įsitikinkite, kad jūsų aplinkoje yra atnaujinta IANA duomenų bazės versija, kad galėtumėte tiksliai tvarkyti laiko juostų konvertavimus.
Geriausios praktikos
- Naudokite ISO 8601 formatą trukmės eilutėms: Tai užtikrina nuoseklumą ir sąveiką.
- Pasirinkite tinkamą Temporal tipą: Naudokite
Temporal.PlainDate
,Temporal.PlainTime
,Temporal.ZonedDateTime
arbaTemporal.Instant
, atsižvelgdami į tai, ar jums reikia laiko juostos palaikymo, ar ne. - Normalizuokite trukmes, kai reikia: Normalizavimas supaprastina trukmes ir palengvina jų palyginimą.
- Atsargiai tvarkykite laiko juostas: Laiko juostų konvertavimai gali būti sudėtingi, todėl naudokite
Temporal.ZonedDateTime
ir žinokite apie vasaros laiko perėjimus. - Apsvarstykite mažiausią vienetą: Apskaičiuodami trukmes, nurodykite mažiausią vienetą, kad gautumėte norimą tikslumo lygį.
- Rašykite vienetų testus: Kruopščiai išbandykite savo kodą, kad įsitikintumėte, jog trukmės skaičiavimai yra tikslūs.
Dažnos klaidos
- Laiko juostų ignoravimas: Neatsižvelgiant į laiko juostas, gali atsirasti netikslių trukmės skaičiavimų, ypač kai dirbate su įvykiais skirtingose vietose.
- Naudojant seną Date objektą: Senasis
Date
objektas yra žinomas dėl savo keistenybių ir nenuoseklumų. Norėdami patikimiau tvarkyti datas ir laikus, pasirinkite Temporal API. - Trukmių nenormalizavimas: Trukmių nenormalizavimas gali apsunkinti palyginimus ir skaičiavimus.
- Neteisingas ISO 8601 formatas: Naudojant neteisingą ISO 8601 trukmės eilutę gali įvykti klaidų.
Realūs naudojimo atvejai įvairiose kultūrose
Temporal API gali būti ypač naudingas pasaulinėse programose, kuriose laiko juostų skirtumai ir kultūriniai niuansai yra reikšmingi. Štai keletas pavyzdžių:
- Pasaulinis įvykių planavimas: Tikslus įvykių planavimas keliose laiko juostose, atsižvelgiant į vasaros laiko perėjimus. Pavyzdžiui, planuojant internetinį seminarą, kuris prasideda 9:00 val. PST, ir rodant atitinkamą pradžios laiką įvairiose laiko juostose, pvz., CET, JST ir AEDT.
- Tarptautinis kelionių planavimas: Kelionės trukmės apskaičiavimas, įskaitant persėdimus ir laiko juostų pakeitimus. Tai naudinga generuojant maršrutus ir valdant skrydžių tvarkaraščius. Pavyzdžiui, apskaičiuojant bendrą kelionės laiką iš Niujorko į Tokiją, įskaitant persėdimą Londone ir koreguojant laiko juostų skirtumus.
- Pasaulinė e. komercija: Numatomo pristatymo laiko rodymas vartotojo vietos laiko juostoje. Tam reikia atsižvelgti į kilmės laiko juostą, pristatymo trukmę ir paskirties laiko juostą. Pavyzdžiui, prekė išsiunčiama iš sandėlio Vokietijoje klientui Australijoje, o numatomas pristatymo laikas yra 7 dienos, rodomas kliento vietos laiku.
- Finansinės operacijos tarp šalių: Tikslus palūkanų kaupimo arba mokėjimo terminų apskaičiavimas skirtinguose regionuose. Tai dažnai apima skirtingų darbo dienų ir švenčių atsižvelgimą kiekvienoje šalyje. Pavyzdžiui, apskaičiuojant palūkanas, sukauptas paskolai Singapūre, atsižvelgiant į Singapūro valstybines šventes.
- Daugiakultūrės kalendoriaus programos: Įvairių kalendoriaus sistemų, tokių kaip islamo ar hebrajų kalendorius, palaikymas ir tikslus įvykių trukmės bei priminimų apskaičiavimas pagal šiuos kalendorius.
- Pasaulinis projektų valdymas: Projektų užduočių trukmės ir terminų stebėjimas paskirstytose komandose, atsižvelgiant į skirtingus darbo grafikus ir laiko juostas.
Išvada
Temporal.Duration
suteikia tvirtą ir intuityvų būdą dirbti su laiko intervalais JavaScript. Suprasdami jo funkcijas ir geriausią praktiką, galite užtikrintai atlikti tikslius ir patikimus trukmės skaičiavimus savo programose. Temporal API įsisavinimas lemia švaresnį, lengviau prižiūrimą kodą ir sumažina klaidų riziką, susijusią su senu datų ir laiko tvarkymu.
Gilinantis į Temporal API, nepamirškite peržiūrėti oficialios dokumentacijos ir eksperimentuoti su skirtingais scenarijais, kad visiškai suvoktumėte jo galimybes. Su savo moderniu dizainu ir išsamiomis funkcijomis Temporal yra pasirengęs pakeisti tai, kaip mes tvarkome datas, laikus ir trukmes JavaScript.