Testy jednostkowe, daty i strefy czasowe

Daty w JavaScript tworzone są w aktualnej strefie czasowej, przynajmniej o ile nie podamy w konstruktorze stringa z uwzględnieniem strefy czasowej. Zmiana czasu między letnim a zimowym lub wykonanie skryptu w innej strefie czasowej (np. na zewnętrznym serwerze ciągłej integracji, znajdującym się na innym kontynencie) da inny wynik niż oryginalnie. O ile w wielu sytuacjach to jak najbardziej pożądane zjawisko, w przypadku testów jednostkowych różnie z tym bywa. Jak zatem używać zawsze „tej właściwej” strefy czasowej?

Od razu przejdę do mięsa, czyli test jednostkowy (Jasmine):

describe("Date", function() {
    it("should show correct hour", function() {
        expect(new Date("2014-04-10 22:00:00+0000").getHours())
            .toBe(0);
    });
});

Powyższy test jednostkowy przejdzie na komputerze w naszej aktualnej strefie czasowej (CEST, czyli Europa Środkowa, czas letni). Ale wystarczy wysłać to do jakiegoś Jenkinsa, czy innego zwierzęcia przeprowadzającego nam ciągłą integrację (a więc i odpalającą testy jednostkowe), z serwerem w innej strefie czasowej, a w niektórych podobnych sytuacjach nawet poczekać do zimy i odpalić ten sam test na własnym komputerze, żeby się wysypał.

Jasne, można sobie dodać/odjąć przesunięcie względem UTC, ale jest jeszcze inne rozwiązanie, moim zdaniem ciekawsze. Nazywa się Moment.js.

Moment.js służy do operowania na datach, ale w sposób bardziej przejrzysty i elastyczny niż natywny obiekt Date. Powyższy test jednostkowy z użyciem Moment.js wyglądałby następująco:

describe("Date", function() {
    it("should show correct hour", function() {
        expect(moment.utc("2014-04-10 22:00:00").zone(-2).hours())
            .toBe(0);
    });
});

Uwagę zwracają dwie rzeczy. Po pierwsze, string z datą przekazany został do funkcji utc(). Służy ona do przestawienia obiektu Moment w tryb UTC. Z kolei funkcja zone() służy do ustawienia strefy czasowej, dla której chcemy pobrać wartość. Tak więc ustawiamy datę dla strefy UTC, ale pobieramy godzinę dla strefy czasowej przesuniętej o dwie godziny. Podany offset można wyrazić również w minutach (-120) lub jako string ("+0200" lub "+02:00"). W ten sposób niezależnie od tego, w jakiej strefie czasowej uruchamiany jest test, zawsze przejdzie.


Napisz komentarz


Szukaj wpisów


Chmura tagów