Dlaczego moment.js śmierdzi?

To będzie krótki post, ale cudaczność tej biblioteki naprawdę zasługuje na oddzielny wpis. Najprostszą odpowiedzią na tytułowe pytanie jest oczywiście to, że moment.js został napisany w JavaScript, a język ten nie słynie z przemyślanych rozwiązań…

W czym rzecz?

Od kilku dni zajmuję się tematem działania datepickera dla różnych ustawień regionalnych. Jak łatwo się domyślić, potrzebowałem w tym celu walidacji daty zgodnie z ustalonym formatem. Ponieważ zabawkowy język do animacji płatków śniegu jakim jest JS, natywnie nie umożliwia zrobienia niczego sensownego z datami, musiałem użyć zewnętrznej biblioteki. Pomyślałem, że zastosuję moment.js, który jest zachwalany jako najlepsze narzędzie do obsługi dat dla JS.

Szybki test:

 1 moment("1.1.2001", "YYYY-MM-DD").isValid()
 2 true
 3 moment("1.13.2001", "YYYY-MM-DD").isValid()
 4 false
 5 moment("13.1.2001", "YYYY-MM-DD").isValid()
 6 true
 7 moment("1.13.2001", "YYYY-MM-DD").isValid()
 8 false
 9 moment("1.13.2001", "YYYY-DD-DD").isValid()
10 true
11 moment("1.13.2001", "YYYY-DD-MM").isValid()
12 false
13 moment("1.13.2001", "momentjs jest fajny").isValid()
14 false

Nie wiem doprawdy, jak można coś takiego osiągnać. Wygląda jak jakieś 10 lat wąchania przeterminowanego sudafedu. Jestem w stanie zrozumieć olewanie konkretnego separatora, trochę mniej olewanie zera wiodącego dla liczby dni/miesięcy, ale kompletne olewanie kolejności? I czemu się nie wywali, gdy dostanie totalna głupotę w formacie?

No nic, cudaczny moment.js poszedł do kosza, okazało się, że są jednak lepsze rozwiązania w półświatku JS.

PS To jednak działa!

Jak zauważył jeden (jedyny?) z czytelników w komentarzach, da się zmusić moment.js do poprawnej walidacji w ten sposób:

1 moment("1.1.2001", "YYYY-MM-DD", true).isValid()
2 false
3 moment("13.1.2001", "YYYY-MM-DD", true).isValid()
4 false
5 moment("1.13.2001", "YYYY-DD-DD", true).isValid()
6 false

I to jest właśnie doskonały przykład code smell. Musimy podać trzeci parametr, koniecznie o wartości true, żeby drugi parametr zaczął działać. Absurd! Taki kod jest mylący i nieintuicyjny. Nie da się po prostu użyć, trzeba się wczytywać w dokumentację. A nawet po jej przeczytaniu właściwie nie wiadomo, o co chodzi, ani dlaczego proste i intuicyjne wywołanie nie zachowuje się zgodnie z oczekiwaniami.

Opublikowano: Ostatnia aktualizacja: