Monolit-IT - Blog - szczegóły

Baza wiedzy

Czas na moment.js

15.10.2018

Często spotykamy się z problemem poprawnego formatowania i parsowania daty i czasu, jak i jego przesyłaniem i przechowywaniem. Podstawowe typy danych w Javascripcie oferują jedną klasę Date, która nadaje się do podstawowych zadań, ale jeżeli chcemy mieć większą kontrolę i swobodę w manipulacji czasem, musimy skorzystać z zewnętrznej biblioteki.

Doskonałym przykładem jest wspomniana w tytule biblioteka moment.js, która nie ma żadnego poważniejszego konkurenta w swojej branży.

Użycie jej jest banalnie proste i zostało przygotowane do wszystkich najważniejszych typów projektów: od zwykłego użycia zminifikowanej wersji bezpośrednio w tagu script, aż do użycia w projekcie node.js z użyciem npm lub nuget. Jeśli piszemy w TypeScript, w pakiecie dostajemy typy, dzięki czemu nie trzeba doinstalowywać typów z DefinitelyTyped.


Biblioteka ta pokrywa ogromny obszar zastosowań. Zacznijmy od prostego przykładu utworzenia podstawowego obiektu moment:

var m = moment();

Powyższa konstrukcja tworzy obiekt moment reprezentujący aktualny czas. Gdy powyższą funkcję wywołamy z parametrem, możemy się spodziewać różnego zachowania w zależności od typu parametru. Przede wszystkim w obiekt moment możemy "zapakować" obiekt typu Date. Jeżeli podamy liczbę, wówczas zostanie to potraktowane jako uniksowy timestamp wyrażony w milisekundach. Jeżeli zaś podamy string, wówczas nastąpi próba parsowania tego napisu do daty. Biblioteka jest oczywiście przygotowana na różne warianty formatu daty i czasu, od typowo amerykańskich formatów do bardziej swojsko wyglądających formatów typu 'YYYY-MM-DD'. Co ważne, jeżeli parsowanie się nie uda, wówczas nie zauważymy żadnego błędu czy wyjątku - obiekt o dziwo zostanie utworzony, ale poprawność obiektu możemy sprawdzić uruchamiając metodę isValid(). Poza podaniem stringa do parsowania możemy podać jeszcze konkretny format:

var m = moment('2018-10-14', 'YYYY-MM-DD');

Jeśli nie jesteśmy pewni co do użytego formatu, możemy podać ich więcej. Wtedy drugi parametr ma postać tablicy stringów.

Myślę, że tak szeroki wachlarz możliwości parsowania daty zadowoli każdego, kto choć raz musiał się zmierzyć z walidacją danych wprowadzanych przez użytkownika. Dotyczy to przede wszystkim frontendu, ale nic nie stoi na przeszkodzie, aby bibliotekę zaprząc do pracy po stronie backendu i walidować dane przychodzące np. z REST-a.

Kolejną ważną cechą biblioteki jest możliwość manipulowania czasem. Mamy do dyspozycji tak podstawowe metody, jak ustawianie poszczególnych fragmentów daty/czasu. Ale najbardziej cenię możliwość dodawania i odejmowania. Myślę, że spotkaliście się nie raz z problemem typu "kiedy to będzie trzy miesiące od 29 lutego" lub inne tego typu dziwne sytuacje. Robimy wówczas tak:

moment().add(3, 'months');

Analogicznie działa metoda substract. Jeżeli z kolei mamy datę, w której chcielibyśmy wyzerować czas do północy, wówczas przyda nam się taka metoda:

moment().startOf('day');

Jedna ważna uwaga - wszelkie operacje na obiekcie moment zmieniają go. Uważajmy więc na sytuacje, w których przekazujemy obiekt moment do jakiejś funkcji, w której wykonamy w/w operację. Bo jeżeli nie było to naszą intencją, przekazany obiekt zostanie zmieniony. Żeby się przed tym ustrzec, musimy wykonać kopię przekazanego obiektu za pomocą metody clone().


Przesyłanie daty pomiędzy frontendem i backendem najlepiej realizować poprzez przesyłanie jej w unixowym timestampie, wówczas przydatna będzie metoda o intuicyjnej nazwie unix():

moment().unix();



No i ostatnia ważna rzecz, to jest formatowanie. Jest to de facto odwrotność parsowania i działają tutaj te same reguły formatowania, jakie są używane przy parsowaniu właśnie. Np.:

moment().format( 'YYYY-MM-DD');



Biblioteka ma całą masę innych metod, które w znacznym stopniu ułatwiają operacje na dacie i czasie:

  • wyznaczanie różnicy pomiędzy dwiema datami wyrażoną w dowolnych jednostkach,
  • porównywanie dwóch dat (czy wcześniejsza, późniejsza, taka sama),
  • internacjonalizację (czyli w skrócie i18n :-),
  • uwzględnianie stref czasowych.

Po szczegóły odsyłam do oficjalnej strony, na której znajdziemy szczegółową dokumentację.

Zainteresował Cię ten wpis?
Chcesz dowiedzieć się więcej?

Michał Gierwatowski

Michał Gierwatowski

Programista wszechstronny, od języka Progress4GL począwszy, przez Javę, na TypeScripcie kończąc. Ponad piętnastoletnie doświadczenie w wytwarzaniu różnego rodzaju systemów informatycznych. Ostatnio interesuje się nowinkami w ekosystemie JavaScript/node.js

Michał.Gierwatowski(at)monolit-it.pl

Zobacz wszystkie artykuły danego autora »