Czas jest jednym z podstawowych “parametrów” świata, który na co dzień wielokrotnie zapisujemy (zapamiętujemy) i przeliczamy. Obecnie oznacza to, że jest przetwarzany przez komputery. Mogło by się wydawać, że sprawa jest prosta, ale od razu widać całą masę kłopotów. Pomysł na ten wpis wynika z bezsensownej zmiany czasu na zimowy w minioną niedzielę.
Po pierwsze strefy czasowe. Dopóki znajdujemy się w jednej strefie czasowej wszystko jest ok, potrafimy bez problemu obliczyć różnicę czasu pomiędzy dwiema datami. Do czasu: mamy przecież w Polsce dwie strefy czasowe – letnią i zimową. Jeżeli interesuje nas dokładne obliczenie czasu to musimy te informacje uwzględniać. Rozwiązaniem tego problemu może być zapamiętywanie i obliczanie dat i czasów w UTC (Universal Time Coordinated). Wiedzę na temat aktualnej w danym momencie i miejscu strefie czasowej najlepiej pobierać z systemu operacyjnego, który powinien to “ogarniać”. Nie warto tego rozgryzać samemu, bo ilość wyjątków jest powalająca. W tym miejscu polecam film The Problem with Time & Timezones.
Do tej pory pamiętam kartkówkę z geografii w liceum na której liczyliśmy czas podróży samolotem z San Francisco to Tokio (i z powrotem) na podstawie godzin przylotów i odlotów. Jedynym rozwiązaniem gwarantującym dobry wynik było przejście do czasu UTC.
Po drugie format zapisu danych. Komputer operuje na liczbach a ludzie na ciągach znaków. Istnieje wiele formatów zapisu daty i czasu w formie ciągu znaków, ale to jest tylko reprezentacja “dla ludzi”. W pamięci data i czas mogą być zapisane na wiele sposobów, z których trzy są moim zdaniem najważniejsze:
- Możemy pamiętać oddzielnie jako liczby całkowite rok, miesiąc, dzień, godzinę, minutę, sekundę i milisekundę (albo nanosekundę itp.) + dodatkowo kod strefy czasowej (zapisany np. w postaci liczby minut w stosunku do UTC). Taki sposób jest dokładny i uniwersalny, ale mało wydajny i pamięciożerny. Ktoś jeszcze pamięta problem roku 2000?
- Drugim sposobem jest zapisywanie epoki unix, czyli ilości sekund od 01-01-1970. Tu problemy są dwa: stosując int32 mamy bardzo ograniczony zakres dat i dokładność na poziomie sekundy.
- Trzecim sposobem, z którym spotykam się na co dzień jest zapisywanie liczby zmiennoprzecinkowej określającej dni od roku 0. Z tej metody korzysta Matlab. Zdecydowaną zaletą jest możliwość opisania dowolnej daty w historii i przyszłości wszechświata oraz możliwość uwzględniania dokładności sub-sekundowej. Wada tego zapisu wynika ze zmiennej dokładności zapisu zmiennoprzecinkowego w zależności od wartości – pisałem o tym kilka tygodni temu.
Zdecydowanie trzeci sposób zapisu daty jest moim ulubionym – pozwala na bardzo szybkie operowanie na datach, bez utraty precyzji. Operacje na liczbach zmiennoprzecinkowych są całkowicie rutynowe, więc ciężko będzie znaleźć coś wydajniejszego.
Bardzo wiele zależy od języka programowania, w każdym jest inne podejście. Szczególnie w Pythonie widać ogrom komplikacji. Jakie są Wasze doświadczenia? Z którego formatu korzystacie najczęściej?
Jako bonus chciałbym Wam pokazać 3 animacje mojego autorstwa. Pierwsza jest dość przewidywalna bo pokazuje czas trwania dnia w zależności od dnia roku:
Dwie kolejne są już dużo ciekawsze, ponieważ pokazują czas wschodu i zachodu słońca w lokalnej strefie czasowej.
Widać wyraźnie zmianę czasu letniego na zimowy (w różnym czasie zależnie od regionu) i słabe dopasowanie strefy czasowej w niektórych regionach.
adres |