Znaczniki czasu Unix i czas epoki: Problem roku 2038 wyjaśniony

Opublikowano: 9:00 AM , przez Redakcja Godzina.org

Znaczniki czasu Unix wyjaśnione: sekundy od epoki 1970, konwersja UTC, przepełnienie roku 2038 o 03:14:07 UTC, 64-bitowe rozwiązanie i sekundy przestępne.

Wyświetlacz zegara cyfrowego przewijający się od 03:14:07 UTC 19 stycznia 2038, ilustrujący przepełnienie 32-bitowego czasu Unix ze znakiem

Czym jest znacznik czasu Uniksa?

Znacznik czasu Uniksa to pojedyncza liczba: liczba sekund, które upłynęły od epoki Uniksa, zdefiniowanej jako 00:00:00 UTC 1 stycznia 1970 roku. To wszystko. Żadnej strefy czasowej, żadnego ciągu znaków z datą, żadnych nazw miesięcy – po prostu liczba całkowita zwiększająca się o jeden na sekundę.

Ponieważ epoka jest stała i uniwersalna, znacznik czasu taki jak 1700000000 oznacza dokładnie tę samą chwilę w każdym miejscu na Ziemi. Serwer w Tokio i laptop w Chicago zgodzą się, że odnosi się on do 14 listopada 2023 roku o 22:13:20 UTC. Lokalne wyświetlanie różni się w zależności od strefy czasowej, ale podstawowa liczba nigdy się nie zmienia.

Jedno celowe uproszczenie: czas Uniksa ignoruje sekundy przestępne. Zakłada, że każdy dzień ma dokładnie 86 400 sekund, co nie jest do końca zgodne z rzeczywistością astronomiczną, ale utrzymuje arytmetykę w czystości. Więcej na ten temat poniżej.

Dlaczego inżynierowie je uwielbiają

Znaczniki czasu są wszechobecne w oprogramowaniu – czasy modyfikacji plików, rekordy baz danych, odpowiedzi API, pola wygaśnięcia JWT, linie logów – i to z dobrego powodu:

  • To pojedyncza wartość. Jedna liczba całkowita przechowuje pełną datę i godzinę. Żadnego parsowania, żadnych niejasności co do MM/DD vs DD/MM.
  • Są niezależne od strefy czasowej. Liczba jest zawsze w UTC. Konwersję do czasu lokalnego wykonujesz tylko wtedy, gdy pokazujesz ją człowiekowi.
  • Łatwo je porównywać i sortować. Które zdarzenie było pierwsze? Mniejsza liczba całkowita. Czas trwania między dwoma zdarzeniami? Odejmij je; odpowiedź jest w sekundach.
  • Są kompaktowe w przechowywaniu. Pojedyncza 4- lub 8-bajtowa liczba całkowita w porównaniu z sformatowanym ciągiem znaków.

Dlatego tak wiele infrastruktury pod maską operuje na sekundach epoki, nawet jeśli interfejs pokazuje ci przyjazne 2026-07-23. Jeśli chcesz przechodzić między tymi dwiema reprezentacjami, konwerter znacznika czasu Unix wykonuje tłumaczenie w obu kierunkach.

Odczytywanie znacznika: praktyczny przykład

Weźmy znacznik czasu 1000000000 – słynny, ponieważ osiągnął tę wartość na żywo w telewizji wśród entuzjastów Uniksa.

Aby odczytać go ręcznie, dzielisz sekundy na większe jednostki. Z grubsza, 1 000 000 000 sekund to około 31,7 roku (rok to ~31 556 952 sekund). Dodaj to do epoki 1970 roku i trafisz do 2001 roku. Dokładny moment to 9 września 2001, 01:46:40 UTC.

Rzadko wykonujesz tę arytmetykę ręcznie – każdy język ma wbudowaną funkcję. W Pythonie:

```python from datetime import datetime, timezone datetime.fromtimestamp(1000000000, tz=timezone.utc)

2001-09-09 01:46:40+00:00

```

Kluczowa kwestia: konwersja jest zawsze zakotwiczona w UTC. Funkcja zamienia surową liczbę sekund na datę kalendarzową, przesuwając się naprzód od epoki. Jeśli zamiast tego chcesz czasu lokalnego, stosujesz przesunięcie strefy czasowej po konwersji UTC – sam znacznik czasu nie niesie żadnej informacji o strefie.

Problem roku 2038

Tutaj historia staje się interesująca – i gdzie wiele w przeciwnym razie dobrze zbudowanych systemów ma w sobie tykający zegar.

Przez dziesięciolecia standardowy typ C używany do przechowywania czasu Uniksa, time_t, był powszechnie 32-bitową liczbą całkowitą ze znakiem. 32-bitowa liczba całkowita ze znakiem może reprezentować wartości od −2 147 483 648 do 2 147 483 647. Ta górna granica jest problemem.

Licząc sekundy od epoki 1970 roku, wartość 2 147 483 647 zostaje osiągnięta o 03:14:07 UTC 19 stycznia 2038 roku. Jedną sekundę później licznik musi stać się 2 147 483 648 – ale ta liczba nie mieści się w 32-bitowej liczbie całkowitej ze znakiem. Zamiast kontynuować wzrost, bity przepełniają się i zawijają do najbardziej ujemnej wartości, −2 147 483 648.

Ujemny znacznik czasu jest interpretowany jako czas przed epoką. Zatem zegar nie tylko się zatrzymuje – przeskakuje wstecz do 13 grudnia 1901 roku. Każdy system, który ufał swojemu 32-bitowemu time_t, nagle wierzy, że jest początek XX wieku.

Często nazywa się to błędem Y2K38 lub błędem milenijnym Uniksa i strukturalnie jest to ten sam rodzaj przepełnienia o stałej szerokości, który napędzał panikę roku 2000 – tyle że dalej w przyszłości i zakorzeniony w ograniczeniach binarnych liczb całkowitych, a nie dwucyfrowych latach.

Gdzie to faktycznie boli

Nowoczesne 64-bitowe komputery stacjonarne i serwery zostały w dużej mierze naprawione lata temu. Ryzyko koncentruje się w miejscach, które są trudne do zaktualizowania:

  • Systemy wbudowane i przemysłowe. Routery, sterowniki, urządzenia medyczne, sterowniki ECU w samochodach i sprzęt IoT, który został dostarczony z 32-bitowym time_t i może działać bez zmian przez 20+ lat. Wiele urządzeń wdrażanych dzisiaj będzie nadal w użyciu w 2038 roku.
  • Starszy kod w C. Aplikacje skompilowane ze starą definicją time_t, zwłaszcza gdy typ przedostał się do formatów dyskowych lub protokołów sieciowych.
  • Stare bazy danych i systemy plików. Formaty przechowywania, które pakowały znaczniki czasu w 32-bitowe pola. Niektóre starsze systemy już wykazują objawy podczas obsługi odległych dat w przyszłości – pomyśl o 20-letniej hipotece lub wygaśnięciu certyfikatu, które sięga poza 2038 rok.

Tryb awarii nie zawsze jest dramatycznym crash'em. Czasami jest to subtelnie błędnie obliczona data: wygasły token, który jest odczytywany jako ważny, kolejność sortowania, która się odwraca, zaplanowane zadanie, które uruchamia się w 1901 roku.

Rozwiązanie: 64-bitowy czas

Rozwiązanie jest w zasadzie proste – rozszerz time_t do 64 bitów. 64-bitowa liczba całkowita ze znakiem może liczyć sekundy daleko poza jakikolwiek praktyczny horyzont: punkt przepełnienia znajduje się około 292 miliardów lat w przyszłości, wygodnie poza przewidywanym czasem życia Słońca.

Większość obecnych systemów operacyjnych już dokonała tego ruchu. 64-bitowy Linux używa 64-bitowego time_t; nawet 32-bitowy Linux zyskał obsługę 64-bitowego czasu w jądrze i glibc w ostatnich latach. Trudną częścią nie jest sama naprawa – chodzi o znalezienie i przebudowanie każdego kawałka oprogramowania układowego, każdego przechowywanego formatu i każdej zewnętrznej binarnej, która wciąż zakłada 32 bity. Ta praca audytowa jest prawdziwym projektem na rok 2038.

Jak pasują sekundy przestępne

Czas astronomiczny i czas atomowy nieznacznie się rozchodzą, więc oficjalny UTC od czasu do czasu wstawia sekundę przestępną, aby utrzymać zegary w zgodzie z obrotem Ziemi. Czas Uniksa, celowo, udaje, że one nie istnieją – na stałe koduje 86 400 sekund na dzień.

Kiedy występuje sekunda przestępna, systemy zazwyczaj ją "rozmazuję" – rozkładając dodatkową sekundę na pewne okno (Google spopularyzował 24-godzinne rozmazywanie), tak aby żaden zegar nigdy nie musiał pokazywać niemożliwego 23:59:60. Konsekwencja: znaczniki czasu Uniksa pozostają gładkie i monotoniczne, kosztem bycia o maleńki ułamek sekundy odbiegające od ścisłego UTC podczas rozmazywania. Dla praktycznie całego oprogramowania jest to dokładnie taki kompromis, jakiego chcesz. Przepełnienie w 2038 roku jest problemem szerokości liczby całkowitej; sekundy przestępne są osobnym, znacznie mniejszym dziwactwem definicyjnym – nie myl ich.

Kluczowe wnioski

  • Znacznik czasu Uniksa to sekundy od 00:00:00 UTC 1 stycznia 1970 roku, z pominięciem sekund przestępnych.
  • To pojedyncza, niezależna od strefy czasowej liczba całkowita – łatwa do przechowywania, porównywania i sortowania.
  • Konwersja jest zawsze względem UTC; czas lokalny jest stosowany później.
  • 32-bitowy time_t ze znakiem przepełnia się o 03:14:07 UTC 19 stycznia 2038 roku, zawijając do wartości ujemnej i przeskakując do 1901 roku.
  • Rozwiązaniem jest 64-bitowy time_t; wysiłkiem jest audyt systemów wbudowanych i starszych.

Chcesz zobaczyć to w akcji? Wklej dowolną wartość epoki do konwerter znacznika czasu Unix, aby odczytać ją jako datę dla człowieka – lub idź w drugą stronę i zamień datę na jej znacznik czasu.

Często zadawane pytania

Czy znacznik czasu Uniksa jest w sekundach czy milisekundach?

Klasyczny czas Uniksa jest w sekundach. Jednak JavaScript i wiele interfejsów API sieciowych używa milisekund od epoki, więc wartość taka jak 1700000000000 jest 1000× większa. Szybka wskazówka: znacznik czasu w sekundach dla niedawnej daty ma 10 cyfr; w milisekundach ma 13. W razie wątpliwości sprawdź wielkość przed konwersją.

Czy problem roku 2038 spowoduje awarię mojego telefonu lub laptopa?

Prawie na pewno nie. Nowoczesne 64-bitowe systemy operacyjne już używają 64-bitowego time_t, co przesuwa przepełnienie o miliardy lat. Prawdziwe zagrożenie istnieje w długowiecznych urządzeniach wbudowanych i starym oprogramowaniu, które wciąż polega na 32-bitowym czasie i może nie zostać zaktualizowane przed 2038 rokiem.

Czy znacznik czasu Uniksa może być ujemny?

Tak. Wartości ujemne reprezentują chwile przed epoką 1970 roku – na przykład -1 to 31 grudnia 1969, 23:59:59 UTC. To jest dokładnie to, co produkuje 32-bitowe przepełnienie w 2038 roku, dlatego zegar wydaje się przeskakiwać z powrotem do 1901 roku.

Dlaczego czas Uniksa ignoruje sekundy przestępne?

Aby utrzymać matematykę prostą i przewidywalną. Traktowanie każdego dnia jako dokładnie 86 400 sekund oznacza, że czasy trwania to tylko odejmowanie, a znaczniki czasu pozostają monotoniczne. Niewielka niezgodność z astronomicznym UTC jest obsługiwana przez "rozmazywanie" sekundy przestępnej, co prawie wszystkie aplikacje wolą od radzenia sobie z przypadkiem brzegowym 23:59:60.

Jak przekonwertować znacznik czasu bez pisania kodu?

Użyj narzędzia online. konwerter znacznika czasu Unix akceptuje wartość epoki i natychmiast pokazuje pasującą datę i godzinę UTC oraz lokalną, a także konwertuje daty kalendarzowe z powrotem na znaczniki czasu.

Czas teraz w te miasta:

Nowy Jork · Londyn · Tokio · Paryż · Hongkong · Singapur · Dubaj · Los Angeles · Szanghaj · Pekin · Sydney · Mumbaj

Czas teraz w krajach:

🇺🇸 USA | 🇨🇳 Chiny | 🇮🇳 Indie | 🇬🇧 Wielka Brytania | 🇩🇪 Niemcy | 🇯🇵 Japonia | 🇫🇷 Francja | 🇨🇦 Kanada | 🇦🇺 Australia | 🇧🇷 Brazylia |

Czas teraz w strefy czasowe:

UTC | GMT | CET | PST | MST | CST | EST | EET | IST | Chiny (CST) | JST | AEST | SAST | MSK | NZST

Darmowe widżety dla webmasterów:

Darmowy widget zegara analogowego | Darmowy widżet zegara cyfrowego | Darmowy widżet zegara tekstowego | Darmowy widżet zegara słownego