Skip to content
Powrót do bloga
Poradniki

Unix timestamp — przewodnik: precyzja, strefy czasu i DST

Unix timestamp w praktyce: czas epoch, konwersja sekund/ms/μs, obsługa stref czasu, pułapki DST oraz przykłady kodu w JS, Pythonie i Go.

14 min czytania

Kompletny przewodnik po Unix timestamp: konwersja sekund/milisekund/mikrosekund i dobre praktyki dla stref czasu

Unix timestamp wyraża czas jako „liczbę sekund, które upłynęły od Unix epoch (1 stycznia 1970, 00:00:00 UTC)”. Ponad 95% serwerów WWW i 90% systemów bazodanowych na świecie używa wewnętrznie tej reprezentacji. Ten przewodnik omawia różnice w precyzji, implementacje w językach programowania, obsługę stref czasu oraz kwestie związane z czasem letnim.

Pochodzenie i definicja Unix timestamp

Unix epoch rozpoczął się 1 stycznia 1970, 00:00:00 UTC. Unix timestamp 0 odpowiada dokładnie temu momentowi, a 1262304000 reprezentuje 2010-01-01 00:00:00 UTC. System domyślnie pomija efekty sekund przestępnych.

Pierwotnie wartość ta była przechowywana jako 32-bitowy integer ze znakiem, co dało początek problemowi roku 2038 — maksymalna wartość przepełnia się 19 stycznia 2038 o 03:14:07 UTC. Współczesne systemy używają 64-bitowych integerów, znacząco wydłużając możliwy do reprezentowania zakres czasu.

Różnice w precyzji czasu

JednostkaLiczba na sekundęCyfryTypowe zastosowania
Sekundy (s)110Tradycyjne systemy Unix/Linux
Milisekundy (ms)1 00013JavaScript, Java, logowanie
Mikrosekundy (μs)1 000 00016Distributed tracing, bazy danych
Nanosekundy (ns)1 000 000 00019Język Go, analiza wydajności

Praktyczna reguła: 10-cyfrowe wartości to zwykle sekundy, 13-cyfrowe — milisekundy, 16-cyfrowe — mikrosekundy, a 19-cyfrowe — nanosekundy.

Timestampy w JavaScripcie

JavaScript natywnie posługuje się milisekundami. Konstruktor Date() zakłada, że podana liczba to milisekundy — dla wartości na poziomie sekund należy ją pomnożyć przez 1000.

// Pobierz bieżący Unix timestamp (w milisekundach)
const timestampMs = Date.now();
console.log(timestampMs);  // Przykładowy wynik: 1692268800123

// Dla timestampów w sekundach: podziel milisekundy przez 1000 i zaokrąglij w dół
const timestampSec = Math.floor(Date.now() / 1000);
console.log(timestampSec); // Przykładowy wynik: 1692268800

// Konwersja Unix timestamp z powrotem na obiekt Date
let ts = 1692268800;
let date = new Date(ts * 1000);
console.log(date.toISOString()); // "2023-08-17T16:00:00.000Z"

Timestampy w Pythonie

Funkcja time.time() w Pythonie zwraca Unix timestamp na poziomie sekund jako liczbę zmiennoprzecinkową:

import time
from datetime import datetime, timezone

# Pobierz bieżący Unix timestamp (sekundy, float)
now_sec = time.time()
print(now_sec)  # Przykładowy wynik: 1692268800.123456

# Pobierz milisekundy (integer)
now_millis = int(time.time() * 1000)
print(now_millis)  # Przykład: 1692268800123

# Pobierz nanosekundy (Python 3.7+)
now_nanos = time.time_ns()
print(now_nanos)  # Przykład: 1692268800123456789

# Konwersja na datetime
ts = 1692268800
dt_local = datetime.fromtimestamp(ts)
dt_utc = datetime.fromtimestamp(ts, timezone.utc)
print(dt_local.strftime("%Y-%m-%d %H:%M:%S"))  # Czas lokalny
print(dt_utc.strftime("%Y-%m-%d %H:%M:%S"))    # Czas UTC

Timestampy w języku Go

Biblioteka time w Go udostępnia kilka poziomów precyzji:

package main

import (
    "fmt"
    "time"
)

func main() {
    // Pobierz bieżący Unix timestamp
    sec := time.Now().Unix()        // Sekundy
    msec := time.Now().UnixMilli()  // Milisekundy (Go 1.17+)
    nsec := time.Now().UnixNano()   // Nanosekundy

    fmt.Println(sec)   // Przykład: 1692268800
    fmt.Println(msec)  // Przykład: 1692268800123
    fmt.Println(nsec)  // Przykład: 1692268800123456789

    // Konwersja timestampu na obiekt Time
    t := time.Unix(sec, 0)
    fmt.Println(t.UTC())
    fmt.Println(t)
}

Częste błędy i dobre praktyki

Przykład błędu: niejasne jednostki

// ✗ Źle: niejasna jednostka timestampu
const timestamp = 1692268800;
const date = new Date(timestamp); // Błąd: traktowane jako milisekundy, pokazuje 1970

// ✓ Poprawnie: jednoznacznie wskazuj jednostki
const timestampSec = 1692268800;
const timestampMs = 1692268800000;
const dateFromSec = new Date(timestampSec * 1000);

Dobra praktyka nazewnictwa pól

log_entry = {
    "timestamp_ms": 1692268800123,           # Poziom milisekund
    "timestamp_iso": "2023-08-17T16:00:00Z", # ISO 8601 UTC
    "event_type": "user_login",
    "user_id": 12345
}

Pułapki obsługi stref czasu

Podczas pracy ze strefami czasu pojawiają się cztery główne pułapki:

  1. Mylenie czasu lokalnego z UTC — Unix timestamp jest zawsze oparty na UTC; konwertuj go na czas lokalny dopiero w momencie wyświetlania
  2. Brak zapisanej informacji o strefie czasu — wprowadza dwuznaczność; zawsze zapisuj UTC lub dołączaj offset
  3. Niespójność stref między systemami — wszystkie systemy powinny używać tej samej referencji strefy (zalecane: UTC)
  4. Ręczne obliczanie offsetów DST — polegaj na wbudowanych bibliotekach, nie na sztywno zakodowanych wartościach

Zalecane podejście: „standardowy zapis, zlokalizowane wyświetlanie”. Na etapach przechowywania i przesyłania używaj UTC lub Unix timestamp dla zapewnienia spójności; przy wyświetlaniu formatuj dane zgodnie ze strefą czasu użytkownika.

Problemy z czasem letnim (DST)

DST tworzy dwa problematyczne okresy:

  • Pominięty czas: gdy zaczyna się czas letni, zegary skaczą do przodu. Przykładowo 02:00 przeskakuje od razu na 03:00, przez co 02:30 nie istnieje.
  • Powtórzony czas: gdy czas letni się kończy, przedział 01:00–01:59 pojawia się dwukrotnie, co rodzi dwuznaczność.

Sam Unix timestamp pozostaje ciągły i nie podlega wpływowi DST, ale konwersje na czas lokalny wymagają staranności.

Dobre praktyki dla logowania, baz danych i API

Systemy logowania

Stosuj jednolitą strefę UTC oraz format ISO 8601; w razie potrzeby dodawaj timestampy z precyzją milisekundową lub mikrosekundową.

Bazy danych

Preferuj natywne typy kalendarzowe ze strefą czasu; dla numerycznych timestampów używaj typu BIGINT i wyraźnie zaznaczaj jednostkę w nazwie pola (np. *_epoch_ms).

API

Jednoznacznie określ format i jednostki. Interfejsy zewnętrzne najlepiej obsługiwać w ISO 8601 (czytelne, zawiera strefę czasu); systemy wewnętrzne mogą korzystać z numerycznych timestampów z udokumentowaną jednostką.

Częste scenariusze błędów

  • Niepowodzenie parsowania 13 cyfr: timestampy milisekundowe podane do funkcji oczekujących sekund powodują overflow. Najpierw określ jednostkę po liczbie cyfr.
  • Niezgodność formatu: nieprawidłowe daty, brakujące strefy czasu lub punkty przejścia DST powodują błędy parsowania.
  • Offsety stref czasu: odchylenia o pełne godziny (±8 h) zwykle wskazują na problem z ujednoliceniem. Zalecane: wewnętrznie używaj UTC.
  • Przepełnienie liczbowe: systemy 32-bitowe napotykają limit 2038; priorytetowo traktuj 64-bitowe integery.

Najczęściej zadawane pytania

Dlaczego 1 stycznia 1970?

Rozwój systemu operacyjnego Unix rozpoczął się w 1970 roku, a był to okrągły rok pełnej dekady — łatwy do zapamiętania i wyliczeń. 32-bitowe integery pozwalały reprezentować daty od 1970 do 2038, co w tamtych czasach było wystarczające.

Jak odróżnić sekundy od milisekund?

Trzy metody: sprawdź liczbę cyfr (10 cyfr = sekundy, 13 = milisekundy, 16 = mikrosekundy, 19 = nanosekundy), zweryfikuj wynik przez sparsowanie i ocenę sensowności daty albo skorzystaj z narzędzia konwersji online.

Czy problem 2038 nadal jest istotny?

Współczesne systemy oparte na 64-bitowych integerach w dużej mierze rozwiązały ten problem. Główne języki programowania obsługują już 64-bitowe timestampy. Starsze systemy 32-bitowe i urządzenia wbudowane mogą jednak nadal wymagać uwagi.

Dlaczego DST sprawia problemy?

Nieciągłość czasu wynikająca z pominiętych godzin oraz powtórzenia powstające z duplikowanych godzin tworzą dwuznaczność przy parsowaniu. Różne systemy obsługują dwuznaczne czasy w różny sposób. Rozwiązanie: wewnętrznie używaj UTC i konwertuj na czas lokalny dopiero przy wyświetlaniu.

Dlaczego timestampy w JavaScripcie i Pythonie się różnią?

Date.now() w JavaScripcie zwraca milisekundy (13 cyfr); time.time() w Pythonie zwraca sekundy (liczba zmiennoprzecinkowa z precyzją mikrosekundową). Konwersja wymaga dzielenia lub mnożenia przez 1000.

Najnowsze trendy i prognozy

  • Większa precyzja: handel finansowy, IoT i systemy czasu rzeczywistego wymagają dokładności na poziomie nanosekund
  • Synchronizacja rozproszona: protokoły NTP i PTP poprawiają dokładność
  • Timestampy w blockchain: kryptowaluty wymagają odpornych na manipulację timestampów o wysokiej precyzji
  • Optymalizacja wydajności: instrukcje SIMD, cache pamięci oraz przetwarzanie równoległe przyspieszają konwersje

Wypróbuj samodzielnie

Konwertuj Unix timestamp natychmiast za pomocą naszego Konwertera Unix timestamp — automatycznie wykrywa sekundy, milisekundy i mikrosekundy. 100% w przeglądarce.

Pracujesz z PostgreSQL? Warto poznać szczegóły dotyczące tego, co tak naprawdę przechowuje kolumna timestamp w PostgreSQL — to osobny temat z własnymi pułapkami stref czasu specyficznymi dla Postgresa.

Podsumowanie

Ten obszerny przewodnik omawia podstawy Unix timestamp — od pochodzenia epoch i konwersji między poziomami precyzji, przez implementacje w różnych językach, obsługę stref czasu, pułapki DST, aż po inżynierskie dobre praktyki w logowaniu, bazach danych i projektowaniu API. Najważniejsza lekcja: przechowuj w UTC, wyświetlaj w czasie lokalnym, i zawsze jednoznacznie określaj jednostki timestampów.

Timestampy to tylko jeden element warsztatu programisty. Warto zapoznać się z szerszym zestawem niezbędnych narzędzi dla programistów obejmujących kodowanie, obliczanie sum kontrolnych (hash) oraz konwersję danych.

Powiązane artykuły

Zobacz wszystkie artykuły