Dansk

En dybdegående guide til JavaScript Temporal API, en moderne løsning til effektiv håndtering af datoer og tider i forskellige internationale sammenhænge.

JavaScript Temporal API: Moderne håndtering af dato og tid for et globalt publikum

JavaScript `Date`-objektet har længe været en kilde til frustration for udviklere. Dets foranderlighed, inkonsistente API og dårlige understøttelse af tidszoner har ført til talrige biblioteker som Moment.js og date-fns for at udfylde hullerne. Nu, med Temporal API, tilbyder JavaScript en moderne, indbygget løsning til håndtering af datoer og tider med forbedret klarhed og præcision. Denne artikel giver en omfattende oversigt over Temporal API, med fokus på dets funktioner, fordele og anvendelse i forskellige internationale sammenhænge.

Hvad er Temporal API?

Temporal API er et nyt, globalt objekt i JavaScript, designet til at løse manglerne ved `Date`-objektet. Det giver en ren, uforanderlig API til at arbejde med datoer, tider, tidszoner og kalendersystemer. Afgørende er, at det sigter mod at repræsentere dato- og tidskoncepter på en måde, der er tættere på den virkelige verdens brug og forventninger, hvilket gør internationalisering meget mere ligetil.

Nøglefunktioner:

Grundlæggende Temporal-objekter

Temporal API introducerer flere nye objekttyper. Her er nogle af de centrale:

Arbejde med datoer

Oprettelse af en `Temporal.PlainDate`

For at oprette en `Temporal.PlainDate` kan du bruge konstruktøren:

const plainDate = new Temporal.PlainDate(2024, 10, 27); // År, Måned (1-12), Dag
console.log(plainDate.toString()); // Udskrift: 2024-10-27

Du kan også bruge `from`-metoden, som accepterer en streng i ISO 8601-format:

const plainDateFromString = Temporal.PlainDate.from('2024-10-27');
console.log(plainDateFromString.toString()); // Udskrift: 2024-10-27

Hentning af datokomponenter

Du kan få adgang til individuelle datokomponenter ved hjælp af egenskaber som `year`, `month` og `day`:

console.log(plainDate.year); // Udskrift: 2024
console.log(plainDate.month); // Udskrift: 10
console.log(plainDate.day); // Udskrift: 27

Datoaritmetik

For at tilføje eller trække dage, uger, måneder eller år fra, skal du bruge `plus`- og `minus`-metoderne. Disse metoder returnerer et nyt `Temporal.PlainDate`-objekt:

const nextWeek = plainDate.plus({ days: 7 });
console.log(nextWeek.toString()); // Udskrift: 2024-11-03

const lastMonth = plainDate.minus({ months: 1 });
console.log(lastMonth.toString()); // Udskrift: 2024-09-27

Sammenligning af datoer

Du kan sammenligne datoer ved hjælp af `compare`-metoden:

const date1 = new Temporal.PlainDate(2024, 10, 27);
const date2 = new Temporal.PlainDate(2024, 11, 15);

console.log(Temporal.PlainDate.compare(date1, date2)); // Udskrift: -1 (date1 er tidligere end date2)

Arbejde med tidspunkter

Oprettelse af en `Temporal.PlainTime`

For at oprette en `Temporal.PlainTime` skal du bruge konstruktøren:

const plainTime = new Temporal.PlainTime(10, 30, 0); // Time, Minut, Sekund
console.log(plainTime.toString()); // Udskrift: 10:30:00

Eller brug `from`-metoden med en ISO 8601-tidsstreng:

const plainTimeFromString = Temporal.PlainTime.from('10:30:00');
console.log(plainTimeFromString.toString()); // Udskrift: 10:30:00

Hentning af tidskomponenter

console.log(plainTime.hour); // Udskrift: 10
console.log(plainTime.minute); // Udskrift: 30
console.log(plainTime.second); // Udskrift: 0

Tidsaritmetik

const later = plainTime.plus({ minutes: 15 });
console.log(later.toString()); // Udskrift: 10:45:00

Arbejde med dato og tid sammen

Oprettelse af en `Temporal.PlainDateTime`

Du kan oprette en `Temporal.PlainDateTime` direkte eller ved at kombinere en `Temporal.PlainDate` og en `Temporal.PlainTime`:

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
console.log(plainDateTime.toString()); // Udskrift: 2024-10-27T10:30:00

const date = new Temporal.PlainDate(2024, 10, 27);
const time = new Temporal.PlainTime(10, 30, 0);
const combinedDateTime = date.toPlainDateTime(time);
console.log(combinedDateTime.toString()); // Udskrift: 2024-10-27T10:30:00

Tidszoner

Korrekt håndtering af tidszoner er afgørende for applikationer, der beskæftiger sig med brugere på forskellige steder. Temporal API giver robust tidszoneunderstøttelse gennem `Temporal.ZonedDateTime`- og `Temporal.TimeZone`-objekterne.

Oprettelse af en `Temporal.ZonedDateTime`

For at oprette en `Temporal.ZonedDateTime` har du brug for en `Temporal.PlainDateTime` og en tidszoneidentifikator. Tidszoneidentifikatorer er baseret på IANA's tidszonedatabase (f.eks. `America/Los_Angeles`, `Europe/London`, `Asia/Tokyo`).

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
console.log(zonedDateTime.toString()); // Udskrift: 2024-10-27T10:30:00-07:00[America/Los_Angeles] (Offset afhænger af regler for sommertid)

Alternativt kan du oprette `Temporal.ZonedDateTime` fra en `Instant`.

const instant = Temporal.Instant.fromEpochSeconds(1666866600); // Eksempel på tidsstempel
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO(timeZone); // Tidszone som 'America/Los_Angeles'
console.log(zonedDateTimeFromInstant.toString());

Konvertering mellem tidszoner

Du kan konvertere en `Temporal.ZonedDateTime` til en anden tidszone ved hjælp af `withTimeZone`-metoden:

const newTimeZone = 'Europe/London';
const zonedDateTimeInLondon = zonedDateTime.withTimeZone(newTimeZone);
console.log(zonedDateTimeInLondon.toString()); // Udskrift: 2024-10-27T18:30:00+01:00[Europe/London]

Arbejde med tidszoneforskydninger

`getOffsetStringFor`-metoden for `Temporal.TimeZone`-objektet giver offset-strengen for en given `Temporal.Instant`:

const timeZoneObject = new Temporal.TimeZone(timeZone);
const offsetString = timeZoneObject.getOffsetStringFor(zonedDateTime.toInstant());
console.log(offsetString); // Udskrift: -07:00 (Afhængigt af regler for sommertid)

Det er vigtigt at bruge de korrekte IANA-tidszoneidentifikatorer for nøjagtige beregninger. Disse identifikatorer vedligeholdes og opdateres regelmæssigt for at afspejle ændringer i sommertid og tidszonegrænser.

Varigheder (Durations)

`Temporal.Duration`-objektet repræsenterer et tidsrum. Det kan bruges til at lægge til eller trække fra datoer og tidspunkter.

Oprettelse af en `Temporal.Duration`

Du kan oprette en `Temporal.Duration` ved hjælp af konstruktøren, hvor du specificerer år, måneder, dage, timer, minutter, sekunder, millisekunder, mikrosekunder og nanosekunder:

const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9); // År, Måneder, Dage, Timer, Minutter, Sekunder, Millisekunder, Mikrosekunder, Nanosekunder
console.log(duration.toString()); // Udskrift: P1Y2M3DT4H5M6.007008009S

Eller ved at bruge en ISO 8601-varighedsstreng:

const durationFromString = Temporal.Duration.from('P1Y2M3DT4H5M6S');
console.log(durationFromString.toString()); // Udskrift: P1Y2M3DT4H5M6S

Tilføjelse af varigheder til datoer og tidspunkter

const plainDate = new Temporal.PlainDate(2024, 10, 27);
const duration = new Temporal.Duration(0, 0, 7); // 7 dage
const newDate = plainDate.plus(duration);
console.log(newDate.toString()); // Udskrift: 2024-11-03

Bemærk, at tilføjelse af varigheder, der involverer måneder eller år, til datoer kræver omhyggelig overvejelse, da antallet af dage i en måned eller et år kan variere.

Kalendersystemer

Temporal API understøtter forskellige kalendersystemer ud over den gregorianske kalender. Dette er afgørende for applikationer, der skal håndtere datoer i forskellige kulturelle sammenhænge. Selvom understøttelsen stadig er under udvikling, giver det et grundlag for fremtidig udvidelse.

Brug af alternative kalendere

For at bruge en specifik kalender kan du specificere den, når du opretter Temporal-objekter:

const hebrewDate = new Temporal.PlainDate(5785, 1, 1, { calendar: 'hebrew' });
console.log(hebrewDate.toString()); // Den specifikke udskrift kan variere afhængigt af implementering og formatering. Kræver polyfill i mange miljøer på skrivende stund.

Vigtigt: Understøttelse af ikke-gregorianske kalendere kan kræve polyfills eller specifik browser-/miljøunderstøttelse. Tjek Temporal API-dokumentationen og browserkompatibilitetstabeller for de seneste oplysninger.

Formatering af datoer og tidspunkter

Mens Temporal API fokuserer på manipulation af dato og tid, håndteres formatering typisk af `Intl.DateTimeFormat`-objektet, som er en del af Internationalization API. Temporal-objekter fungerer problemfrit med `Intl.DateTimeFormat`.

Brug af `Intl.DateTimeFormat`

Her er, hvordan du formaterer en `Temporal.PlainDate` ved hjælp af `Intl.DateTimeFormat`:

const plainDate = new Temporal.PlainDate(2024, 10, 27);
const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatter.format(plainDate)); // Udskrift: October 27, 2024

const formatterGerman = new Intl.DateTimeFormat('de-DE', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatterGerman.format(plainDate)); // Udskrift: 27. Oktober 2024

Du kan tilpasse formateringsindstillingerne, så de passer til dine behov. Det første argument til `Intl.DateTimeFormat` er lokaliteten (locale), som bestemmer sproget og de regionale konventioner, der bruges til formatering. Brug af forskellige lokaliteter (f.eks. 'en-US', 'de-DE', 'fr-FR', 'ja-JP') producerer forskellige outputformater.

Formatering af `Temporal.ZonedDateTime`

Formatering af `Temporal.ZonedDateTime` er lignende, men du kan også inkludere tidszoneinformation i outputtet:

const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);

const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' });
console.log(formatter.format(zonedDateTime)); // Udskrift: October 27, 2024, 10:30 AM PDT (Tidszoneforkortelsen afhænger af regler for sommertid)

Bedste praksis for internationalisering

Når du arbejder med datoer og tider i en global sammenhæng, skal du huske følgende bedste praksis:

Sammenligning af Temporal API med det gamle Date-objekt

Her er en tabel, der fremhæver de vigtigste forskelle og fordele ved Temporal API sammenlignet med det gamle `Date`-objekt:

Funktion Gammelt `Date`-objekt Temporal API
Foranderlighed Foranderligt (modificerer det oprindelige objekt) Uforanderligt (returnerer nye objekter)
Tidszoneunderstøttelse Begrænset og ofte problematisk Robust og nøjagtig, baseret på IANA's tidszonedatabase
API Inkonsistent og vanskeligt at bruge Klart, konsekvent og intuitivt
Præcision Millisekund Nanosekund
Kalendersystemer Begrænset til gregoriansk Understøtter alternative kalendersystemer (med understøttelse under udvikling)
Internationalisering Kræver eksterne biblioteker for robust internationalisering Indbygget understøttelse og problemfri integration med `Intl.DateTimeFormat`

Browserunderstøttelse og Polyfills

Som et relativt nyt API er browserunderstøttelsen for Temporal API stadig under udvikling. Tjek de seneste browserkompatibilitetstabeller (f.eks. på MDN Web Docs) for at se, hvilke browsere og miljøer der understøtter det indbygget. For ældre browsere eller miljøer uden indbygget understøttelse kan du bruge polyfills til at levere Temporal API-funktionaliteten. Søg efter "Temporal API polyfill" på nettet for at finde egnede muligheder.

Konklusion

JavaScript Temporal API repræsenterer et betydeligt fremskridt i håndteringen af datoer og tider i JavaScript. Dets uforanderlighed, klare API, robuste tidszoneunderstøttelse og kalendersystemfunktioner gør det til et kraftfuldt værktøj for udviklere, der bygger applikationer, der skal arbejde med datoer og tider nøjagtigt og pålideligt i forskellige internationale sammenhænge. Selvom browserunderstøttelsen stadig er under udvikling, gør fordelene ved Temporal API det værd at lære og tage i brug til nye projekter. Ved at omfavne Temporal API og følge bedste praksis for internationalisering kan du skabe applikationer, der giver en problemfri og nøjagtig dato- og tidsoplevelse for brugere over hele verden.

Yderligere læsning