CodeGym /Kursy /SQL SELF /Praca z czasem Unix: EPOCH

Praca z czasem Unix: EPOCH

SQL SELF
Poziom 32, Lekcja 1
Dostępny

Czas Unix to po prostu sposób zapisywania czasu jako liczby sekund (czasem milisekund), które upłynęły od północy 1 stycznia 1970 roku według UTC. Ten format jest mega popularny w programowaniu: łatwo go przechowywać, przesyłać i porównywać, bo to po prostu liczba.

Uproszczając, czas Unix to taki timer, który zaczął tykać w 1970 roku i nie przestaje. Widzisz dziwną liczbę typu 1697222400? Nie panikuj — to tylko liczba sekund, które minęły od początku odliczania. Chcesz wiedzieć, jaka to data? Zaraz nauczysz się to liczyć!

Taki format często używa się przy synchronizacji danych między systemami, do przechowywania znaczników czasu i kiedy trzeba szybko sprawdzić, co było wcześniej, a co później.

Konwersja do czasu Unix

W PostgreSQL jest specjalna funkcja EXTRACT(EPOCH FROM ...), która pozwala przekonwertować datę lub znacznik czasu na czas Unix.

Przekonwertujmy aktualną datę do tego formatu:

SELECT EXTRACT(EPOCH FROM NOW());

Wynik będzie wyglądał mniej więcej tak:

1697222400

Ten wynik to po prostu aktualna data i godzina w sekundach od 1970 roku.

A tak można przekonwertować konkretną datę:

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2023-10-01 12:00:00');

Wynik:

1696152000

Teraz wiemy, że 1 października 2023 o 12:00 UTC to właśnie ta wartość.

Konwersja z czasu Unix

Oczywiście jest też funkcja odwrotna. Jeśli masz czas Unix i chcesz go przekonwertować na czytelny dla człowieka format, pomoże ci funkcja TO_TIMESTAMP().

Przekonwertujmy czas Unix na datę i godzinę

SELECT TO_TIMESTAMP(1697222400);

Wynik:

2023-10-13 00:00:00+00

Teraz widzimy, że to data 13 października 2023 o 00:00 UTC.

Praktyczne użycie czasu Unix

Załóżmy, że mamy tabelę events, gdzie trzymamy info o zdarzeniach, w tym ich znaczniki czasu w formacie Unix.

CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    event_name TEXT,
    event_time BIGINT -- do przechowywania czasu Unix
);

Możemy wrzucić dane do tej tabeli, podając znaczniki czasu w formacie Unix:

INSERT INTO events (event_name, event_time)
VALUES
('Uruchomienie serwera', 1697222400),
('Aktualizacja bazy danych', 1697308800);

Żeby przekonwertować te dane na czytelny format, wystarczy użyć TO_TIMESTAMP:

SELECT event_name, TO_TIMESTAMP(event_time) AS readable_time
FROM events;

Wynik:

event_name readable_time
Uruchomienie serwera 2023-10-13 00:00:00+00
Aktualizacja bazy danych 2023-10-14 00:00:00+00

Tipy i typowe błędy

  1. Zły wybór precyzji

Jeśli twój czas Unix jest w milisekundach (np. 1697222400000), nie możesz go po prostu wrzucić do TO_TIMESTAMP albo użyć w EXTRACT. W takim przypadku trzeba podzielić wartość przez 1000:

SELECT TO_TIMESTAMP(1697222400000 / 1000);

Wynik:

2023-10-13 00:00:00+00
  1. Ignorowanie stref czasowych

Czas Unix jest w UTC, więc wyniki zawsze będą bez uwzględnienia strefy czasowej, jeśli nie przekonwertujesz czasu specjalnie. Na przykład:

SELECT TO_TIMESTAMP(1697222400) AT TIME ZONE 'Europe/Moscow';

Wynik:

2023-10-13 03:00:00
  1. Problemy ze zbyt dużymi liczbami

Czasem programiści przypadkiem podają za dużą wartość czasu Unix (np. milisekundy zamiast sekund). To prowadzi do błędnych wyników:

SELECT TO_TIMESTAMP(1697222400000); -- Będzie błąd!

Żeby to naprawić, trzeba poprawnie podzielić liczbę przez 1000.

Przykład: obliczanie czasu wykonania zadania

Weźmy przykład z życia: mamy tabelę zadań tasks i chcemy policzyć, ile czasu minęło od utworzenia każdego zadania.

Tworzymy tabelę:

CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    task_name TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

Dodajemy kilka zadań:

INSERT INTO tasks (task_name)
VALUES
('Zadanie 1'),
('Zadanie 2'),
('Zadanie 3');

Teraz możemy dodać kolumnę z czasem Unix:

SELECT id, task_name, EXTRACT(EPOCH FROM created_at) AS created_epoch
FROM tasks;

Wynik:

id task_name created_epoch
1 Zadanie 1 1697222400
2 Zadanie 2 1697233200

I policzmy, ile czasu minęło od utworzenia w sekundach:

SELECT id, task_name, EXTRACT(EPOCH FROM NOW()) - EXTRACT(EPOCH FROM created_at) AS elapsed_seconds
FROM tasks;

Wynik:

id task_name elapsed_seconds
1 Zadanie 1 3600
2 Zadanie 2 7200

Kiedy i po co używać czasu Unix?

Czas Unix jest idealny do przechowywania danych czasowych przy przesyłaniu wartości między systemami, porównywaniu znaczników czasu i innych zadaniach, gdzie liczy się minimalne obciążenie procesora. Jest szeroko używany w API, webdevie, analityce, a także do synchronizacji aplikacji serwerowych i klienckich. Ale zawsze pamiętaj o jego cechach: UTC, różne jednostki (sekundy lub milisekundy) i format przechowywania.

Jeśli musisz integrować się z zewnętrznymi systemami, które "gadają czasem Unix", teraz już wiesz, jak z nim pracować w PostgreSQL. Śmiało używaj TO_TIMESTAMP i EXTRACT(EPOCH) do konwersji w obie strony i wszystkie twoje czasowe zadania będą ogarnięte!

2
Zadanie
SQL SELF, poziom 32, lekcja 1
Niedostępne
Obliczanie przedziałów czasowych
Obliczanie przedziałów czasowych
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION