Od bardzo, bardzo długiego czasu w moim notatniku wisiał pomysł pokazania jak nietrywialnym problemem jest prawidłowa obsługa dat w świecie programistycznym. W końcu zdecydowałem się to zrobić.

Cykl artykułów "Vademecum Juniora"

Ten wpis jest częścią cyklu, w ramach którego opisuję moje doświadczenia i spostrzeżenia na temat programistycznego rzemiosła. Cykl jest dedykowany osobom rozpoczynającym swoją przygodę z zawodowym programowaniem lub planują taki krok w przyszłości.

Artykuły składające się na Vademecum Juniora zawierają różne porady, wskazówki i przykłady z pracy jako programista. Nie są one ani uporządkowane chronologicznie, ani mocno ze sobą powiązane. Możesz je więc czytać niezależnie od siebie i w dowolnej kolejności. Polecam jednak zapoznać się z treścią wszystkich wpisów, gdyż wierzę, że z każdego możesz dowiedzieć się czegoś wartościowego.

Esencja tematu w dwóch prezentacjach

I kiedy się za to zabrałem przyszła mi do głowy pewna myśl. Stwierdziłem, że nie będę w stanie opowiedzieć o tym lepiej niż dwie prezentacje, które miałem okazję kiedyś zobaczyć. Postanowiłem więc cały artykuł oprzeć na nich, dodając kilka zdań od siebie.

Tomasz Nurkiewicz i jego Krótka historia czasu

Pierwszą prezentację, autorstwa Tomka Nurkiewicza, oglądałem na żywo w trakcie Confitury w 2013 roku. Wywarła ona na mnie ogromne wrażenie. Zresztą nie tylko na mnie, bo Tomek zgarnął wtedy nagrodę za najlepsze wystąpienie tej konferencji.

Tom ScottThe Problem with Time & Timezones (na kanale Computerphile)

Druga prezentacja, Toma Scotta na kanale Computerphile, wpadła mi w ręce dużo później, chociaż pochodzi z tego samego roku, co ta pierwsza. O ile prezentacja Tomka odnosi się w dużej mierze do Javy, to prezentacja Toma jest bardziej „generyczna”.

Działania arytmetyczne na datach

Obstawiam, że po obejrzeniu obydwu prezentacji Twój mózg nieco się nagrzał 😉 Jeżeli chcesz jeszcze dorzucić do pieca, to przeczytaj o ciekawym przypadku opisanym na Stack Overflow. Mózg eksplodował? No właśnie!

Opisany przypadek jest niezwykle specyficzny i ciężko na niego tak po prostu trafić, ale mimo tego nawet prosta arytmetyka wykonywana na datach może okazać się podchwytliwa.

Problem z schedulerem

Sam kiedyś potknąłem się o tego typu błąd. Niestety nie pamiętam jak to dokładnie wyglądało, bo było to ładnych kilka lat temu, ale postaram się przedstawić chociaż zarys problemu. Pamiętam, że na produkcji mieliśmy pewną aplikację generującą jakieś raporty z określonego okresu. W tle, raz dziennie działał scheduler, który generował raport dla danych od pierwszego dnia poprzedniego miesiąca do tego samego dnia co dzisiejszy, ale z miesiąca poprzedniego. A więc zadanie odpalone 15 kwietnia generowało raport dla danych od 1 do 15 marca. Jakoś tak.

Na początku marca zgłosił się klient, że w raportach nie zostały uwzględnione dni od 29 do 31 stycznia. O co chodziło? Proste – luty miał 28 dni, a więc ostatni raport z lutego obejmował dane od 1 do 28 stycznia. Kolejny odpalił się 1 marca i obejmował dane z… 1 lutego.

No dobra, przyznaję – mogło być zupełnie inaczej 😉 Tzn. nie do końca zupełnie. Problem był zbliżony do tego co opisałem, a jego meritum leżało właśnie w znikających dniach ze względu na nie do końca przemyślaną logikę związaną z arytmetyką na datach.

Jedno źródło dat w całej aplikacji (i poza nią)

Oprócz powyższego problemu z schedulerem w swojej karierze natrafiłem na jeszcze jeden dokuczliwy problem. Jego genezy można upatrywać w zbyt dużej ilości źródeł czasu w naszej aplikacji. Tomek, w swojej prezentacji wspominał o dobrej praktyce przygotowania sobie serwisu do zarządzania czasem w naszej aplikacji, który byłby jedynym źródłem pobierania bieżącej daty i godziny.

Chodzi o to, żeby zamiast strzelania w całej aplikacji java.time.LocalDateTime.now() stworzyć podobny serwis i używać go wszędzie gdzie potrzebujemy czasu:

Ogromnym benefitem używania takiego serwisu, o którym wspominał Tomek, jest możliwość przygotowania dowolnej innej implementacji na potrzeby pisania testów.

Ja bym poszedł jeszcze o krok dalej i rekomendował użycie takiego serwisu we wszystkich częściach aplikacji, nie tylko w kodzie backendu. Użyłbym go również do generowania dat i czasu, które mają powędrować do bazy danych, czy zostać wyświetlone na frontendzie. Dlaczego? Już opowiadam.

Dane z przyszłości

Utrzymywałem kiedyś aplikację, która przy zapisywaniu nowych rekordów do bazy danych korzystała z Oracle’owego SYSDATE do generowania dat utworzenia i ostatniej modyfikacji rekordu. Wszystko działało poprawnie dopóki czas serwera bazy danych i czas serwera aplikacji były takie same. Któregoś dnia jednak ktoś zdecydował o przeniesieniu bazy danych na serwer położony o trzy strefy czasowe później. Po kilku dniach przyszło zgłoszenie klienta, że w aplikacji pojawiają się rekordy z przyszłości 😉

Od tamtej pory, gdzie tylko mogę staram się przekazywać czas z jednego miejsca (backendu aplikacji) do wszystkich zależnych od niego miejsc.

Podsumowanie

Mam nadzieję, że ta mała porcja wiedzy uzmysłowiła Ci jak nietrywialnym problemem może być igranie z czasem 😉 Daj znać w komentarzach jakie są Twoje doświadczenia związane z oprogramowywaniem czasu. Ile razy coś „wybuchło” bo wystąpił mniejszy lub większy problem z datami?


Bądź na bieżąco!

Podobają Ci się treści publikowane na moim blogu? Nie chcesz niczego pominąć? Zachęcam Cię do subskrybowania kanału RSS, polubienia fanpage na Facebooku, zapisania się na listę mailingową:

Dołączając do newslettera #NoweRozdanie2 otrzymasz dostęp do dodatkowych materiałów:

  • PDF: „Jednoosobowa działalność gospodarcza krok po kroku” (do artykułu)
  • PDF: „FAQ: Jak pracuje się dla Roche/Sii?” (do artykułu)
  • PDF: „Jak zmniejszyć prawdopodobieństwo wystąpienia kontroli i co zrobić kiedy urzędnik zapuka do Twoich drzwi?” (do artykułu)

Powyższe dane są przechowywane w systemie Mailchimp i nie są udostępniane nikomu innemu. Więcej szczegółów znajdziesz na stronie polityki prywatności.

lub śledzenia mnie na Twitterze. Generalnie polecam wykonanie wszystkich tych czynności, bo często zdarza się tak, że daną treść wrzucam tylko w jedno miejsce. Zawsze możesz zrobić to na próbę, a jeśli Ci się nie spodoba – zrezygnować :)

Dołącz do grup na Facebooku

Chcesz więcej? W takim razie zapraszam Cię do dołączenia do powiązanych grup na Facebooku, gdzie znajdziesz dodatkowe informacje na poruszane tutaj tematy, możesz podzielić się własnymi doświadczeniami i przemyśleniami, a przede wszystkim poznasz ludzi interesujących się tą samą tematyką co Ty.

W grupie Programista Na Swoim znajdziesz wiele doświadczonych osób chętnych do porozmawiania na tematy krążące wokół samozatrudnienia i prowadzenia programistycznej działalności gospodarczej. Vademecum Juniora przeznaczone jest zaś do wymiany wiedzy i doświadczeń na temat życia, kariery i problemów (niekoniecznie młodego) programisty.

Wesprzyj mnie

Jeżeli znalezione tutaj treści sprawiły, że masz ochotę wesprzeć moją działalność online, to zobacz na ile różnych sposobów możesz to zrobić. Niezależnie od tego co wybierzesz, będę Ci za to ogromnie wdzięczny.

Postaw mi kawę na buycoffee.to

Na wsparciu możesz także samemu zyskać. Wystarczy, że rzucisz okiem na listę różnych narzędzi, które używam i polecam. Decydując się na skorzystanie z któregokolwiek linku referencyjnego otrzymasz bonus również dla siebie.

Picture Credits