Zarządzanie datą i czasem

modyfikacja |

Przeglądarki

Temporal API to narzędzie wprowadzone do JavaScript 2024 roku, które ułatwia pracę z datami, czasem oraz strefami czasowymi i formatowaniem. Ma zastąpić obiekt Date. Obecnie żadna przeglądarka jeszcze nie obsługuje Temporal API.

Node.js

Instalacja

Mimo, iż żadna przeglądarka jeszcze nie obsługuje Temporal API, to można z niego korzystać, przy użyciu Node.js. Utwórz folder, w którym utworzymy bardzo prosty i podstawowy projekt. Za pomocą konsoli, przejdź do folderu i utwórz wstępną konfigurację za pomocą polecenia

npm init

Następnie należy zainstalować paczkę Temporal.

npm install @js-temporal/polyfill

W naszym projekcie będzie również potrzebny Snowpack.

npm install --save-dev snowpack

Upewnij się, że w pliku package.json w script jest komenda uruchamiająca "start": "snowpack dev".

Plik package.json

 "scripts": {
    "start": "snowpack dev",
  },

Tworzenie projektu

W folderze projektu utwórz plik index.html, w którym dołączymy plik temporal.js.

Plik index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Temporal API</title>
    <script defer src="temporal.js" type="module"></script>
  </head>
  <body></body>
</html>

Następnie utwórz plik temporal.js.

Plik temporal.js

import { Temporal } from "@js-temporal/polyfill";

const now = Temporal.Now.plainDateISO();
console.log(now.toString());

W terminalu za pomocą komendy npm run start uruchom projekt i wejdź w konsolę przeglądarki. Utworzony console.log(), powinien wyświetlić aktualną datę, na przykład 2024-09-25. Jeżeli tak się stało, można testować Temporal API.

Temporal.PlainDate

Ustawianie daty

Obiekt PlainDate reprezentuje datę bez czasu i strefy czasowej. Do obiektu możemy podać datę na trzy sposoby. Data musi być podana w kolejności rok-miesiąc-dzień.

Temporal.PlainDate

const example1= new Temporal.PlainDate(2024, 9, 25);
console.log(example1.toString());

const example2 = Temporal.PlainDate.from("2024-09-25");
console.log(example2.toString());

const example3 = Temporal.PlainDate.from({ year: 2024, month: 9, day: 25 });
console.log(example3.toString());

Powyższy consol.log() wyświetli datę, która została wprowadzona. Prawdopodobnie częściej będziesz używał drugiej metody, dlatego dalsze przykłady będą wykorzystywać from().

W trzecim sposobie podawania daty, month jest liczony od 1 nie do 0 do 11 jak to jest w przypadku Date.

Informacje na temat daty

Mając przypisaną datę do obiektu Temporal.PlainDate, możemy uzyskać dowolne informacje na temat tej daty. Poniżej przykład pobierania roku, miesiąca, kodu miesiąca oraz dnia.

const infoDate = Temporal.PlainDate.from("2024-09-25");
console.log(infoDate.year, infoDate.month, infoDate.monthCode, infoDate.day);

// Konsola wyświetli
// 2024 9 M09 25

Wszystkie poniższe wartości, są wartościami tylko do odczytu.

  • year – podaje rok w postaci 4 cyfr
  • month – podaje miesiąc, na przykład dla września będzie to 9
  • monthCode – podaje kod miesiąca, na przykład dla września będzie to M09
  • day – wyświetli dzień na przykład 25

Z podanej daty możemy uzyskać znacznie więcej informacji

const moreInfoDate = Temporal.PlainDate.from("2024-09-25");
console.log(
  moreInfoDate.dayOfWeek,
  moreInfoDate.dayOfYear,
  moreInfoDate.weekOfYear,
  moreInfoDate.yearOfWeek,
  moreInfoDate.daysInWeek,
  moreInfoDate.daysInMonth,
  moreInfoDate.daysInYear,
  moreInfoDate.monthsInYear,
  moreInfoDate.inLeapYear
);

// Konsola wyświetli
// 3 269 39 2024 7 30 366 12 true

Wszystkie poniższe wartości, są wartościami tylko do odczytu.

  • dayOfWeek – podaje dzień tygodnia w postaci liczby
  • dayOfYear – podaje, który to dzień roku
  • weekOfYear – podaje numer tygodnia
  • yearOfWeek – podaje numer roku odpowiadający numerowi tygodnia, często to samo co year
  • daysInWeek – podaje ilość dni w tygodniu
  • daysInMonth – podaje ilość dnie w miesiącu
  • daysInYear – podaje ilość dni w roku
  • monthsInYear – podaje ilość miesięcy w roku
  • inLeapYear – podaje czy rok jest rokiem przestępnym, jeżeli tak zwraca true

Modyfikacja daty

Metody do modyfikacji daty, jakie posiada Temporal.PlainDate są następujące.

  • add({ years, month, days }) – dodaje do daty, lata, miesiące, dni
  • subtract({ years, month, days }) – odejmuje od daty lata, miesiące, dni
  • until() – zwraca różnicę między dwiema datami
  • equals() – sprawdza czy daty są takie same

Poniżej przykłady wyżej wymienionych metod. Należy pamiętać, że Temporal.PlainDate, jest typu immutable, co oznacza, że jest zwracana nowa instancja, a nie modyfikacja istniejącego obiektu.

const methodDate1 = Temporal.PlainDate.from("2024-09-25");
const methodDate2 = Temporal.PlainDate.from("2025-05-15");

console.log(methodDate1.add({ years: 4, months: 4 }).toString());
console.log(methodDate1.subtract({ days: 25 }).toString());
console.log(methodDate1.until(methodDate2).days);
console.log(methodDate1.equals(methodDate2));

// Konsola kolejno wyświetli
// 2029-01-25
// 2024-08-31
// 232
// false

Formatowanie lokalne

Pewnie jak zauważyłeś, aby wyświetlić datę w konsoli trzeba posłużyć się metodą toString(). Dzieje się tak dlatego, że metody zwracają nowy obiekt. Lepszą metodą może się okazać toLocaleString(), która daje większe możliwości wyświetlania daty. Poniższy przykład wyświetla datę do jakiej jesteśmy przyzwyczajeni.

const localePL1 = Temporal.PlainDate.from("2024-09-25");
console.log(localePL1.toLocaleString("pl-PL"));

// Wynik konsoli
// 25.09.2024

Argumenty i konstrukcja formatowania daty są takie same jak w Intl.DateTimeFormat, o którym możesz przeczytać na blogu.

const localePL2 = Temporal.PlainDate.from("2024-09-25");
console.log(localePL2.toLocaleString("pl-PL", { weekday: "long" }));

// Wynik konsoli
// środa

Temporal.PlainTime

Ustawianie czasu

Obiekt PlainTime reprezentuje czas bez daty i strefy czasowej. Podobnie jak w Temporal.PlainDate, czas możemy podać na różne sposoby. Dane należy podawać w kolejności godziny-minuty-sekundy-milisekundy-mikrosekundy-nanosekundy.

const exsampleTime1 = new Temporal.PlainTime(13, 37, 43);
console.log(exsampleTime1.toString());

// Wynik konsoli
// 13:37:43

const exsampleTime2 = Temporal.PlainTime.from("13:37:43");
console.log(exsampleTime2.toString());

// Wynik konsoli
// 13:37:43

const exsampleTime3 = Temporal.PlainTime.from({
  hour: 13,
  minute: 37,
  second: 43,
  millisecond: 68,
  microsecond: 246,
  nanosecond: 205,
});
console.log(exsampleTime3.toString());

// Wynik konsoli
// 13:37:43.068246205

Informacje na temat czasu

Mając przypisany czas do obiektu Temporal.PlainTime, możemy uzyskać dowolne informacje na temat tego czasu. Poniżej przykład pobierania godziny, minuty, sekundy, milisekundy, mikrosekundy oraz nanosekundy.

const infoTime = Temporal.PlainTime.from({
  hour: 13,
  minute: 37,
  second: 43,
  millisecond: 68,
  microsecond: 246,
  nanosecond: 205,
});
console.log(
  infoTime.hour,
  infoTime.minute,
  infoTime.second,
  infoTime.millisecond,
  infoTime.microsecond,
  infoTime.nanosecond
);

// Wynik w konsoli
// 13 37 43 68 246 205

Wszystkie poniższe wartości, są wartościami tylko do odczytu.

  • hour – podaje godzinę
  • minute – podaje minutę
  • second – podaje sekundę
  • millisecond – podaje milisekundę
  • microsecond – podaje mikrosekundę
  • nanosecond – podaje nanosekunde

Modyfikacja czasu

Metody do modyfikacji czasu, jakie posiada Temporal.PlainTime są następujące.

  • add({ hours, minutes, seconds, millisecond, microsecond, nanosecond }) – dodaje do czasu, godziny, minuty, sekundy, milisekundy, makrosekundy, nanosekundy
  • subtract({ hours, minutes, seconds, millisecond, microsecond, nanosecond }) – odejmuje do czasu, godziny, minuty, sekundy, milisekundy, makrosekundy, nanosekundy
  • until() – zwraca różnicę między dwiema czasami
  • equals() – sprawdza czy czasy są takie same

Poniżej przykłady wyżej wymienionych metod. Należy pamiętać, że Temporal.PlainTime, jest typu immutable, co oznacza, że jest zwracana nowa instancja, a nie modyfikacja istniejącego obiektu.

const methodTime1= Temporal.PlainTime.from("13:37:43");
const methodTime2 = Temporal.PlainTime.from("22:39:09");
console.log(methodTime1.add({ hours: 2 }).toString());
console.log(methodTime1.subtract({ hours: 2, minutes: 38 }).toString());
console.log(methodTime1.until(methodTime2).toString());
console.log(methodTime1.equals(methodTime2));

// Kolejno wynik konsoli
// 15:37:43
// 10:59:43
// PT9H1M26S -> oznacza 9 godzin 1 minuta i 26 sekund
// flase

W przypadku zwracanej różnicy czasu można pobrać każdą z wartości osobna.

const duration = methodTime1.until(methodTime2);
console.log(
  "Godzin: ", duration.hours,
  " Minut: ", duration.minutes,
  " Sekund: ", duration.seconds
);

// Wynik konsoli
// Godzin:  9  Minut:  1  Sekund:  26

Formatowanie czasu

Używając metody toString() do wyświetlenia czasu, możemy określić co chcemy wyświetlić. Poniższy czas zostanie wyświetlony tylko do minut.

const formatTime = Temporal.PlainTime.from("13:37:43");
console.log(formatTime.toString({ smallestUnit: "minute" }));

// wynik konsoli
// 13:37

Temporal.PlainDataTime

Łączy w sobie datę i czas. Nie będę się rozpisywał na jej temat, gdyż metody oraz informacje jakie możemy uzyskać na temat daty i czasu są bardzo podobne do tego co posiada Temporal.PlainDate oraz Temporal.PlainTime. Po szczegóły odsyłam do dokumentacji.

Temporal.ZonedDateTime

Łączy w sobie datę i czas oraz strefę czasową. Nie będę się rozpisywał na jej temat, gdyż metody oraz informacje jakie możemy uzyskać na temat daty i czasu są bardzo podobne do tego co posiada Temporal.PlainDate oraz Temporal.PlainTime. Po szczegóły odsyłam do dokumentacji.

Jedną z metod, których nie ma Temporal.PlainDate oraz Temporal.PlainTime jest withTimeZone. Mając zdefiniowaną datę i czas, może sprawdzić jaka w tym samym czasie była data oraz czas w innej strefie czasowej.

const inWarsaw = Temporal.ZonedDateTime.from("2022-01-28T19:53+01:00[Europe/Warsaw]");
const inTokyo = inWarsaw.withTimeZone("Asia/Tokyo");
console.log(inWarsaw.toString(), inTokyo.toString());

// Wynik konsoli
// 2022-01-28T19:53:00+01:00[Europe/Warsaw] 2022-01-29T03:53:00+09:00[Asia/Tokyo]

Temporal.Now

Posiada zestaw metod, która pobierania bieżącą datę i czasu.

zonedDateTimeISO()

Zwraca aktualny czas w konkretnej strefie czasowej. Pełna lista nazw stref czasowych jest dostępna na Wikipedi.

console.log(`Aktualny czas: ${Temporal.Now.zonedDateTimeISO()}`);

// Wynik konsoli, data i czas będą różne w zależności od uruchomienia kodu
// Aktualny czas: 2024-09-27T22:56:39.708599662+02:00[Europe/Warsaw]

Podając konkretną strefę czasową, możemy uzyskać datę oraz czas z dowolnego miejsca.

const timeZone = ["America/New_York", "Europe/London", "Asia/Tokyo"];
timeZone.forEach((time) => {
  console.log(Temporal.Now.zonedDateTimeISO(time).toString());
});

// Wynik konsoli, data i czas będą różne w zależności od uruchomienia kodu
// 2024-09-27T17:01:26.319886317-04:00[America/New_York]
// 2024-09-27T22:01:26.320886319+01:00[Europe/London]
// 2024-09-28T06:01:26.32188632+09:00[Asia/Tokyo]

instant()

Zwraca aktualną datę i czas bez względu na strefę czasową.

console.log(Temporal.Now.instant().toString());

// Wynik w konsoli, data i czas będą różne w zależności od uruchomienia kodu
// 2024-09-27T21:11:28.232488231Z

timeZoneId()

Zwraca nazwę strefy czasowej.

console.log(Temporal.Now.timeZoneId().toString());

// Wynik w konsoli
// Europe/Warsaw

plainDateTimeISO()

Zwraca bieżącą datę oraz czas. Jako parametr można podać strefę czasową.

console.log(Temporal.Now.plainDateTimeISO().toString());

// Wynik w konsoli, data i czas będą różne w zależności od uruchomienia kodu
// 2024-09-27T23:16:40.443800442

plainDateISO()

Zwraca aktualną datę. Jako parametr można podać strefę czasową.

console.log(Temporal.Now.plainDateISO().toString());

// Wynik konsoli
// 2024-09-27

plainTimeISO()

Zwraca aktualny czas. Jako parametr można podać strefę czasową.

console.log(Temporal.Now.plainTimeISO().toString());

// Wynik konsoli
// 23:25:20.908320907

Odczyt danych z Temporla.Now

Jeżeli chcemy odczytać wybrany fragment danych, który otrzymujemy od Temporal.Now, mamy do dyspozycji wszystkie właściwości, które posiadają Temporal.PlainDate oraz Temporal.PlainTime. Poniżej kilka przykładów.

const currentTime = Temporal.Now.zonedDateTimeISO();
console.log(
  "Date",
  currentTime.year,
  currentTime.month,
  currentTime.dayOfYear,
  currentTime.weekOfYear,
  " Time",
  currentTime.hour,
  currentTime.minute
);

// Wynik konsoli
// Date 2024 9 271 39  Time 23 52

Więcej obiektów Temporal

Myślę, że przedstawiłem najważniejsze obiekty Temporal, oraz jak się nimi posługiwać. Jednak to nie wszystko co mamy do dyspozycji. Poniżej lista tego co nie przedstawiłem.

  • Temporal.Duration – reprezentuje odstęp czasowy
  • Temporal.Calendar – reprezentuje kalendarz
  • Temporal.TimeZone – reprezentuje strefę czasową
  • Temporal.Instant – reprezentuje punkt w czasie niezależnie od strefy czasowej
  • Temporal.PlainYearMonth – reprezentuje odpowiednio rok i miesiąc
  • PlainMonthDay – reprezentuje odpowiednio miesiąc i dzień

Tutaj zostawiam link do pełnej dokumentacji Temporal.

Zamiast toString()

W wielu przypadkach, aby wyświetlić datę lub czas trzeba użyć toString(), gdyż zwracany jest obiekt. Myślę, że wygodniej jest zastosować `${}`. Poniżej przykład, w którym console.log zwróci dokłądnie to samo.

const string = Temporal.PlainDate.from("2024-09-25");
console.log(string.add({ hours: 2 }).toString());
console.log(`${string.add({ hours: 2 })}`);

W praktyce

Wyświetlanie czasu jest praktycznie wszędzie. Czy to aplikacja czy zwykły blog, na którym wyświetlana jest data wpisu czy komentarza. W przypadku obliczeń czasu między datami Temporal zwraca liczbę. Idealnie to się będzie łączyć z Intl.DateTimeFormat lub Intl.RelativeTimeFormat, które przedstawiam w tym artykule.

Obliczanie i wyświetlanie czasu do wydarzenia

const startEvent = Temporal.PlainDate.from("2025-03-25");
const simulationDateNaw = Temporal.PlainDate.from("2024-10-15");

const formatRelativeA = new Intl.RelativeTimeFormat(undefined, {
  localeMatcher: "best fit",
  numeric: "always",
  style: "short",
});

console.log(
  "Start wydarzenia",
  formatRelativeA.format(simulationDateNaw.until(startEvent).days, "day")
);

// Wynik konsoli
// Start wydarzenia za 161 dni

W przypadku realnego wydarzenia na stronie należy użyć Temporal.Now, aby zwrócić dzisiejszą datę. Przyda się taż warunek if, który zamieni tekst "Start wydarzenia" na "Wydarzenie odbyło się", kiedy wynik porównania daty będzie ujemny. Jak widać powyższy kod jest dużo czytelniejszy i krótszy od obecnie używanej funkcji Date.

Podobał się artykuł?

Tagi

Komentarze

Brak komentarzy. Bądź pierwszą osobą, która zostawi komentarz!

Zostaw komentarz

Wszystkie pola są wymagane.

Proszę o podanie treści komentarza.

Proszę o podanie imienia.