Unix time wygląda jak najprostszy sposób zapisu czasu: jedna liczba opisuje, ile jednostek upłynęło od wspólnego początku. Łatwo ją sortować, porównywać i przesyłać między systemami. Problemy zaczynają się, gdy kontrakt nie mówi, czy jednostką są sekundy czy milisekundy, lokalna data zostaje potraktowana jak moment, albo zegar systemowy skacze podczas pomiaru timeoutu. Timestamp upraszcza zapis chwili, ale nie zastępuje pełnego modelu czasu.

Epoch daje wspólny punkt odniesienia

Unix time liczy nominalnie sekundy od 1 stycznia 1970 o 00:00:00 UTC. Wartości dodatnie opisują późniejsze chwile, a implementacje obsługujące liczby ze znakiem mogą reprezentować wcześniejsze.

Moment można przechować bez rozpisywania roku, miesiąca i strefy. Dopiero warstwa prezentacji przelicza go na lokalny kalendarz użytkownika.

Sekundy i milisekundy wyglądają równie wiarygodnie

Systemy unixowe często używają sekund, JavaScript milisekund, a telemetryka mikro- lub nanosekund. Pomyłka o współczynnik tysiąc nadal daje poprawną liczbę, tylko datę daleko w przyszłości albo w pobliżu 1970 roku.

Jednostka powinna być widoczna w nazwie, typie lub schema. Heurystyka oparta na liczbie cyfr zawodzi dla danych historycznych i wraz z upływem lat.

Instant nie posiada lokalnej strefy

Konkretny moment jest taki sam na całym świecie. „14:00 w Warszawie” to jego lokalna prezentacja zależna od daty i reguł strefy. Konwersja zmienia zegar i czasem dzień, ale nie wydarzenie.

Dla logu, płatności i wiadomości jest to pożądane. Dla urodzin, święta albo „codziennie o 9:00” sama chwila nie zachowuje intencji kalendarzowej.

UTC jest referencją, nie pełnym interfejsem

Backend może przechowywać zdarzenia w UTC, unikając lokalnych niejednoznaczności. Użytkownik nadal oczekuje własnej strefy i formatu. Renderowanie powinno nastąpić dopiero na granicy prezentacji.

Reguły cyklicznej nie należy raz przeliczyć na UTC i stale dodawać 24 godziny. Po zmianie czasu lokalna godzina się przesunie. Nazwa strefy musi pozostać częścią reguły.

Leap seconds nie pasują idealnie do prostej osi

UTC czasami dodawało sekundę, aby pozostać blisko obrotu Ziemi. Systemy mogą ją pomijać, powtarzać oznaczenie albo rozkładać korektę w czasie. Klasyczny timestamp nie jest jednolicie interpretowany w tym wyjątkowym momencie.

Dla większości aplikacji biznesowych różnica jest mało istotna. Dla precyzyjnej telemetryki i kolejności rozproszonych zdarzeń warto znać zachowanie platformy.

Zegar ścienny może cofnąć się lub skoczyć

NTP, administrator lub hypervisor może poprawić systemowy czas. Dwa kolejne odczyty wall clock nie gwarantują dodatniej różnicy. Pomiar czasu wykonania i timeout powinien używać zegara monotonicznego.

Wall clock odpowiada na pytanie „kiedy według kalendarza”, monotonic na „ile upłynęło od startu”. Zamiana tych pojęć daje losowe retry i wygasania.

Precyzja zapisu nie oznacza dokładności

Nanosekundowe pole może mieć dziewięć cyfr, nawet jeśli fizyczny zegar aktualizuje się co milisekundę, a hosty różnią się o więcej. Dodatkowe miejsca nie gwarantują kolejności.

API powinno obiecywać tylko potrzebną precyzję. Baza i serializer mogą zaokrąglać; round-trip test pokazuje rzeczywistą zachowaną wartość.

Duże timestampy przekraczają typy klientów

Nanosekundy od epoch nie mieszczą się dokładnie w zwykłym Number JavaScript. Historyczny problem roku 2038 dotyczy 32-bitowych sekund ze znakiem. Dokument JSON może być poprawny, a klient mimo to zmienić wartość.

Rozwiązaniem jest string, BigInt-compatible format albo standardowy tekst czasu. Wybór trzeba przetestować we wszystkich wspieranych SDK.

Tekst ISO bywa łatwiejszy do audytu

2026-06-06T12:30:00Z pokazuje datę, czas i UTC. Offset +02:00 również określa jednoznaczny instant. String jest dłuższy, ale człowiek łatwiej zauważa pomyłkę.

API powinno wybrać kanoniczny profil: wymagany offset, dozwoloną precyzję i zasady parsowania. „Prawie ISO” bez strefy ponownie tworzy niejasność.

Typy baz danych mają różną semantykę

Timestamp with time zone może normalizować moment, choć nie przechowuje nazwy regionu. Typ bez strefy zachowuje lokalne pola. Zachowanie zależy od engine, drivera i session timezone.

Migracja starych wartości wymaga znajomości pierwotnej strefy. Jeżeli została utracona, nie ma jednej poprawnej konwersji do UTC.

Serializacja musi zachować kolejność i jednostkę

API, event i baza mogą używać różnych typów. Konwersja przez liczbę zmiennoprzecinkową może utracić precyzję, a serializer może obciąć część ułamkową. W kontrakcie warto określić nie tylko format, ale także sposób zaokrąglania i zachowanie wartości poza obsługiwanym zakresem.

Round-trip powinien przejść przez rzeczywiste SDK, kolejkę i storage. Test samej funkcji daty nie wykryje, że pośredni system zmienił milisekundy na sekundy.

Timestamp w logu potrzebuje kontekstu zdarzenia

Czas utworzenia, otrzymania i przetworzenia wiadomości są różnymi momentami. Jeden ogólny timestamp utrudnia analizę opóźnień. Nazwane pola pozwalają oddzielić zegar producenta od obserwacji konsumenta.

Przy clock skew kolejność tych wartości może wyglądać nielogicznie. Request ID, sequence i host pomagają zrozumieć, czy problem dotyczy sieci, kolejki czy synchronizacji zegara.

Rozproszona kolejność potrzebuje czegoś więcej

Zegary hostów różnią się, a sieć opóźnia wiadomości. Timestamp nie gwarantuje przyczynowej ani transakcyjnej kolejności. Sekwencja, log offset lub wersja bazy daje mocniejszą właściwość.

Czas nadal pomaga w obserwacji i przybliżonym sortowaniu. Nie powinien udawać konsensusu, którego infrastruktura nie zapewnia.

Dobry kontrakt nazywa rodzaj czasu

Pole powinno być instantem, lokalną datą, duration albo regułą cykliczną. Dla timestampu trzeba podać jednostkę, precyzję i zakres. Strefa użytkownika jest decyzją późniejszej prezentacji.

Unix time świetnie reprezentuje konkretną chwilę. Problemy pojawiają się dopiero wtedy, gdy każdą kalendarzową potrzebę próbuje się zamknąć w tej samej nagiej liczbie.