En omfattande guide till JavaScripts Temporal API för exakta och intuitiva tidsintervallsberäkningar, från grundläggande skapande till avancerad aritmetik.
JavaScript Temporal Duration: Bemästra beräkningar av tidsintervall
JavaScripts Temporal API introducerar ett modernt och kraftfullt sätt att hantera datum, tider och tidsintervall. Temporal.Duration
-objektet representerar en tidslängd och erbjuder ett tydligt och intuitivt tillvägagångssätt för att utföra beräkningar med tidsintervall. Den här artikeln går igenom detaljerna i Temporal.Duration
och visar hur man skapar, manipulerar och formaterar varaktigheter för olika användningsfall.
Vad är Temporal.Duration?
Temporal.Duration
representerar ett tidsspann, uttryckt i år, månader, dagar, timmar, minuter, sekunder och bråkdelar av en sekund (millisekunder, mikrosekunder, nanosekunder). Till skillnad från Date
-objekt som representerar en specifik tidpunkt, representerar Temporal.Duration
en tidsmängd. Det följer ISO 8601-formatet för varaktighet (t.ex. representerar P1Y2M10DT2H30M
1 år, 2 månader, 10 dagar, 2 timmar och 30 minuter). Temporal API är utformat för att vara mer intuitivt och mindre felbenäget än det äldre Date
-objektet.
Skapa Temporal.Duration-objekt
Det finns flera sätt att skapa Temporal.Duration
-objekt:
1. Från ett vanligt objekt
Du kan skapa en varaktighet genom att skicka ett objekt med de önskade egenskaperna:
const duration = new Temporal.Duration(1, 2, 10, 2, 30, 0, 0, 0);
console.log(duration.toString()); // Utskrift: P1Y2M10DT2H30M
Detta skapar en varaktighet på 1 år, 2 månader, 10 dagar, 2 timmar och 30 minuter. Notera att argumenten motsvarar följande ordning: years
, months
, weeks
, days
, hours
, minutes
, seconds
, milliseconds
, microseconds
, nanoseconds
.
2. Från en ISO 8601-sträng
Du kan också skapa en varaktighet från en ISO 8601-varaktighetssträng med hjälp av Temporal.Duration.from()
:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.toString()); // Utskrift: P1Y2M10DT2H30M
Detta är särskilt användbart när man hanterar varaktigheter som lagras i strängformat eller tas emot från en extern källa.
3. Använda metoderna add()
och subtract()
med Temporal.Instant
, Temporal.ZonedDateTime
, etc.
När du adderar eller subtraherar Temporal.Duration
från andra Temporal-typer (som Temporal.Instant
eller Temporal.ZonedDateTime
), returneras en Temporal.Duration
som representerar skillnaden mellan de två tidpunkterna om du sedan subtraherar dem. Till exempel:
const now = Temporal.Now.zonedDateTimeISO();
const later = now.add({ hours: 5 });
const duration = later.since(now);
console.log(duration.toString()); // Utskrift: PT5H
Åtkomst till varaktighetskomponenter
Du kan komma åt de enskilda komponenterna i ett Temporal.Duration
-objekt med hjälp av dess egenskaper:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
console.log(duration.years); // Utskrift: 1
console.log(duration.months); // Utskrift: 2
console.log(duration.days); // Utskrift: 10
console.log(duration.hours); // Utskrift: 2
console.log(duration.minutes); // Utskrift: 30
console.log(duration.seconds); // Utskrift: 0
console.log(duration.milliseconds); // Utskrift: 0
console.log(duration.microseconds); // Utskrift: 0
console.log(duration.nanoseconds); // Utskrift: 0
Utföra aritmetik med varaktigheter
Temporal.Duration
-objekt stöder addition och subtraktion med metoderna add()
och subtract()
. Dessa metoder returnerar ett nytt Temporal.Duration
-objekt som representerar resultatet av operationen.
const duration1 = Temporal.Duration.from("P1Y2M");
const duration2 = Temporal.Duration.from("P3M4D");
const addedDuration = duration1.add(duration2);
console.log(addedDuration.toString()); // Utskrift: P1Y5M4D
const subtractedDuration = duration1.subtract(duration2);
console.log(subtractedDuration.toString()); // Utskrift: P10M26D
Du kan också kedja dessa metoder för mer komplexa beräkningar:
const duration = Temporal.Duration.from("P1D").add({ hours: 12 }).subtract({ minutes: 30 });
console.log(duration.toString()); // Utskrift: P1DT11H30M
Metoden negated()
returnerar ett nytt Temporal.Duration
-objekt där alla komponenter är negerade:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const negatedDuration = duration.negated();
console.log(negatedDuration.toString()); // Utskrift: -P1Y2M10DT2H30M
Metoden abs()
returnerar ett nytt Temporal.Duration
-objekt där alla komponenter är positiva värden (absolutvärden):
const duration = Temporal.Duration.from("-P1Y2M10DT2H30M");
const absoluteDuration = duration.abs();
console.log(absoluteDuration.toString()); // Utskrift: P1Y2M10DT2H30M
Metoden with()
låter dig skapa en ny Temporal.Duration
-instans där vissa, eller alla, egenskaper har ändrats till nya värden. Om ett värde inte anges i argumentobjektet kommer det ursprungliga värdet för varaktigheten att användas. Till exempel:
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const newDuration = duration.with({ years: 2, days: 5 });
console.log(newDuration.toString()); // Utskrift: P2Y2M5DT2H30M
Normalisera varaktigheter
Varaktigheter kan ibland uttryckas i en icke-normaliserad form (t.ex. P1Y12M
, vilket skulle kunna förenklas till P2Y
). Metoden normalized()
försöker förenkla en varaktighet till dess mest kompakta form. Den kräver dock ett referensdatum för att hantera komplexiteten med varierande månadslängder. För att normalisera korrekt behöver du en instans av Temporal.PlainDate
, Temporal.ZonedDateTime
eller Temporal.Instant
.
Till exempel, för att normalisera en varaktighet som involverar månader och dagar krävs ett referensdatum:
const duration = Temporal.Duration.from("P1M32D");
const referenceDate = Temporal.PlainDate.from("2024-01-01");
const normalizedDuration = duration.normalized({ relativeTo: referenceDate });
console.log(normalizedDuration.toString()); // Utskrift: P2M1D
I detta exempel normaliseras varaktigheten P1M32D
relativt till 1 januari 2024, vilket resulterar i P2M1D
eftersom januari har 31 dagar.
Om du bara hanterar tidskomponenter (timmar, minuter, sekunder, etc.), kan du normalisera utan ett referensdatum:
const duration = Temporal.Duration.from("PT25H61M");
const normalizedDuration = duration.normalized({ relativeTo: null }); //eller utelämna relativeTo-argumentet
console.log(normalizedDuration.toString()); // Utskrift: P1DT2H1M
Jämföra varaktigheter
Du kan jämföra varaktigheter med metoden compare()
. Denna metod returnerar:
- -1 om den första varaktigheten är kortare än den andra varaktigheten.
- 0 om varaktigheterna är lika.
- 1 om den första varaktigheten är längre än den andra varaktigheten.
const duration1 = Temporal.Duration.from("P1Y");
const duration2 = Temporal.Duration.from("P6M");
const comparisonResult = Temporal.Duration.compare(duration1, duration2);
console.log(comparisonResult); // Utskrift: 1
Praktiska exempel
1. Beräkna tiden till en händelse
Anta att du vill beräkna den återstående tiden till en specifik händelse. Använd Temporal.Now.zonedDateTimeISO()
för att få den aktuella tiden, och subtrahera händelsens datum. Om händelsens datum har passerat blir resultatet negativt.
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()); // Utskrift: t.ex. P262DT14H30M (beroende på aktuellt datum och tid)
2. Spåra varaktigheten för projektuppgifter
Inom projektledning kan du använda Temporal.Duration
för att spåra den uppskattade eller faktiska varaktigheten för uppgifter.
const task1EstimatedDuration = Temporal.Duration.from("PT8H"); // 8 timmar
const task2EstimatedDuration = Temporal.Duration.from("PT16H"); // 16 timmar
const totalEstimatedDuration = task1EstimatedDuration.add(task2EstimatedDuration);
console.log(`Total estimated duration: ${totalEstimatedDuration.toString()}`); // Utskrift: Total estimated duration: P1DT
3. Beräkna ålder
Även om exakt åldersberäkning kräver att man tar hänsyn till skottår och tidszoner, kan Temporal.Duration
ge en rimlig uppskattning:
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`); // Utskrift: Estimated age: 33 years
4. Visa läsbara varaktigheter
Ofta behöver du visa varaktigheter i ett mänskligt läsbart format. Även om Temporal.Duration
inte har inbyggda formateringsfunktioner kan du skapa anpassad formateringslogik:
function formatDuration(duration) {
const parts = [];
if (duration.years) parts.push(`${duration.years} år`);
if (duration.months) parts.push(`${duration.months} månad${duration.months > 1 ? 'er' : ''}`);
if (duration.days) parts.push(`${duration.days} dag${duration.days > 1 ? 'ar' : ''}`);
if (duration.hours) parts.push(`${duration.hours} timme${duration.hours > 1 ? 'ar' : ''}`);
if (duration.minutes) parts.push(`${duration.minutes} minut${duration.minutes > 1 ? 'er' : ''}`);
if (duration.seconds) parts.push(`${duration.seconds} sekund${duration.seconds > 1 ? 'er' : ''}`);
return parts.join(', ');
}
const duration = Temporal.Duration.from("P1Y2M10DT2H30M");
const formattedDuration = formatDuration(duration);
console.log(formattedDuration); // Utskrift: 1 år, 2 månader, 10 dagar, 2 timmar, 30 minuter
Avancerad användning och överväganden
1. Hantering av tidszoner
När man hanterar tidsintervall som korsar tidszonsgränser eller övergångar till sommartid, är det avgörande att använda Temporal.ZonedDateTime
för att säkerställa korrekta beräkningar. Att använda Temporal.PlainDate
och Temporal.PlainTime
undviker alla tidszonskonverteringar.
2. Minsta enhet och avrundning
Metoderna `since()` och `until()` accepterar ofta alternativ för att definiera den minsta enheten för den resulterande varaktigheten. Till exempel för att beräkna tiden *till* en händelse och begränsa resultatet till dagar.
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()); //exempelutskrift PT340D
3. Skottsekunder
Temporal tar inte hänsyn till skottsekunder automatiskt. Om du kräver extrem precision måste du hantera skottsekunder separat.
4. IANA-tidszoner
Temporal API förlitar sig på IANA (Internet Assigned Numbers Authority) tidszonsdatabas. Se till att din miljö har en uppdaterad version av IANA-databasen för att hantera tidszonskonverteringar korrekt.
Bästa praxis
- Använd ISO 8601-format för varaktighetssträngar: Detta säkerställer konsekvens och interoperabilitet.
- Välj lämplig Temporal-typ: Använd
Temporal.PlainDate
,Temporal.PlainTime
,Temporal.ZonedDateTime
ellerTemporal.Instant
beroende på om du behöver tidszonsstöd eller inte. - Normalisera varaktigheter när det behövs: Normalisering förenklar varaktigheter och gör dem lättare att jämföra.
- Hantera tidszoner noggrant: Tidszonskonverteringar kan vara komplexa, så använd
Temporal.ZonedDateTime
och var medveten om övergångar till sommartid. - Tänk på den minsta enheten: När du beräknar varaktigheter, specificera den minsta enheten för att få önskad precision.
- Skriv enhetstester: Testa din kod noggrant för att säkerställa att varaktighetsberäkningar är korrekta.
Vanliga fallgropar
- Ignorera tidszoner: Att inte ta hänsyn till tidszoner kan leda till felaktiga varaktighetsberäkningar, särskilt när man hanterar händelser på olika platser.
- Använda det gamla Date-objektet: Det gamla
Date
-objektet är känt för sina egenheter och inkonsekvenser. Föredra Temporal API för mer tillförlitlig hantering av datum och tid. - Att inte normalisera varaktigheter: Att inte normalisera varaktigheter kan göra jämförelser och beräkningar mer komplexa.
- Felaktigt ISO 8601-format: Att använda en ogiltig ISO 8601-varaktighetssträng kan orsaka fel.
Verkliga användningsfall i olika kulturer
Temporal API kan vara särskilt fördelaktigt i globala applikationer där tidszonsskillnader och kulturella nyanser är betydande. Här är några exempel:
- Global händelseplanering: Schemalägg händelser exakt över flera tidszoner, med hänsyn till övergångar till sommartid. Till exempel, att schemalägga ett webbinarium som börjar kl. 09:00 PST och visa motsvarande starttid i olika tidszoner som CET, JST och AEDT.
- Internationell reseplanering: Beräkna restider, inklusive mellanlandningar och tidszonsändringar. Detta är användbart för att generera resplaner och hantera flygscheman. Till exempel, beräkna den totala restiden från New York till Tokyo, inklusive en mellanlandning i London och justering för tidszonsskillnader.
- Global e-handel: Visa beräknade leveranstider i användarens lokala tidszon. Detta kräver att man beaktar ursprungstidszonen, leveranstiden och destinationstidszonen. Till exempel, en vara som skickas från ett lager i Tyskland till en kund i Australien, med en beräknad leveranstid på 7 dagar, visas i kundens lokala tid.
- Gränsöverskridande finansiella transaktioner: Beräkna ränteperiodisering eller betalningsfrister korrekt över olika regioner. Detta innebär ofta att man måste ta hänsyn till olika arbetsdagar och helgdagar i varje land. Till exempel, beräkna räntan på ett lån i Singapore, med hänsyn till singaporianska helgdagar.
- Multikulturella kalenderapplikationer: Stödja olika kalendersystem, såsom den islamiska eller hebreiska kalendern, och korrekt beräkna varaktigheter och påminnelser för händelser baserat på dessa kalendrar.
- Global projektledning: Spåra varaktigheter och deadlines för projektuppgifter i distribuerade team, med hänsyn till olika arbetsscheman och tidszoner.
Slutsats
Temporal.Duration
erbjuder ett robust och intuitivt sätt att arbeta med tidsintervall i JavaScript. Genom att förstå dess funktioner och bästa praxis kan du med säkerhet utföra exakta och tillförlitliga varaktighetsberäkningar i dina applikationer. Att anamma Temporal API leder till renare, mer underhållbar kod och minskar risken för fel som är förknippade med äldre hantering av datum och tid.
När du fördjupar dig i Temporal API, kom ihåg att konsultera den officiella dokumentationen och experimentera med olika scenarier för att fullt ut förstå dess kapacitet. Med sin moderna design och omfattande funktioner är Temporal redo att revolutionera hur vi hanterar datum, tider och varaktigheter i JavaScript.