Dzisiaj znowu pogadamy o błędach. Bo praca z datami i czasem to trochę jak spacer po polu minowym: wszystko spoko, dopóki nie zrobisz pierwszego kroku w złą stronę.
Błędy przy wyborze typu danych
Tu często zaczynają się wszystkie kłopoty. Zły wybór typu danych może zniweczyć cały twój wysiłek przy pracy z datami i czasem.
Sytuacja 1: Użycie DATE zamiast TIMESTAMP
Kiedy zapisujesz zdarzenie, które ma nie tylko datę, ale też godzinę, użycie tylko DATE może sprawić, że stracisz ważne info.
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
order_date DATE -- tylko data
);
Przy takim designie nie dowiesz się, czy dwa zamówienia były rano czy wieczorem. Po co w ogóle tracić okazję na kawę i patrzenie na fajne timestampy?
Sytuacja 2: Zapomniane strefy czasowe
Jeśli twoja apka działa z użytkownikami z różnych krajów, ale zapisujesz datę i czas tylko przez TIMESTAMP, bez uwzględnienia stref czasowych, twoje dane mogą stać się "bezdomne". TIMESTAMPTZ rozwiązuje ten problem za ciebie.
CREATE TABLE events (
event_time TIMESTAMP -- bez strefy czasowej
);
Nikt nie chce pomylić wieczornego eventu w Nowym Jorku z porannym w Tokio. Używaj TIMESTAMPTZ!
Błędy przy używaniu funkcji
Sytuacja 1: Zły format w TO_CHAR()
Problemy zaczynają się, jeśli źle podasz format. Na przykład:
SELECT TO_CHAR(NOW(), 'YYYY-DD-MM'); -- Ups, pomyliłem miesiąc z dniem
Zamiast klasycznego rok-miesiąc-dzień, dostaliśmy rok-dzień-miesiąc. To może prowadzić do śmiesznych (ale nie zawsze fajnych) sytuacji dla twoich userów. Zawsze sprawdzaj format.
Sytuacja 2: Błędy przy użyciu TO_DATE()
Na odwrót, jeśli próbujesz zamienić string na datę, ale format się nie zgadza, PostgreSQL wywali błąd.
SELECT TO_DATE('10/31/2023', 'YYYY-MM-DD'); -- Błąd! Format się nie zgadza.
Format stringa musi dokładnie pasować do tego, co podałeś. Na przykład:
SELECT TO_DATE('2023-10-31', 'YYYY-MM-DD'); -- Wszystko OK.
Błędy z przedziałami czasowymi
Sytuacja 1: Niejawne rzutowanie typów
Czasem możesz zapomnieć o specyfice rzutowania typów. Na przykład:
SELECT NOW() + '1'; -- BŁĄD! Nie wiadomo, co to jest '1'.
PostgreSQL nie kuma, że chcesz dodać jeden dzień. Poprawnie będzie tak:
SELECT NOW() + INTERVAL '1 day';
Sytuacja 2: Zamieszanie przy odejmowaniu przedziałów
Bądź czujny, dodając lub odejmując przedziały:
SELECT NOW() - INTERVAL '-1 day'; -- To doda dzień zamiast odjąć!
Podwójny minus daje odwrotny efekt. Lepiej unikać takich konstrukcji.
Błędy przy zaokrąglaniu i obcinaniu danych
Sytuacja 1: Złe obcinanie z DATE_TRUNC()
Kiedy używasz DATE_TRUNC() do grupowania danych, zawsze sprawdź, czy wybrałeś właściwy poziom. Na przykład:
SELECT DATE_TRUNC('hour', NOW()); -- Obcina do początku godziny
SELECT DATE_TRUNC('minute', NOW()); -- Obcina do początku minuty
Jeśli spodziewałeś się innego wyniku, a dostałeś coś innego, może wybrałeś zły poziom.
Sytuacja 2: Zapomnienie o strefach czasowych z DATE_TRUNC()
Jeśli pracujesz z czasem w różnych strefach, wynik może być zaskakujący:
SELECT DATE_TRUNC('day', NOW() AT TIME ZONE 'UTC');
Upewnij się, że strefa czasowa jest ustawiona poprawnie, bo inaczej możesz się zgubić w czasie (dosłownie).
Czas Unix: zgubione sekundy
Czas Unix (EPOCH) — wygodna rzecz, ale podstępna. Najczęstszy błąd to pomyłka między sekundami a milisekundami.
SELECT TO_TIMESTAMP(1680000000); -- To jest OK (sekundy).
SELECT TO_TIMESTAMP(1680000000000); -- To błąd! Za dużo zer.
Sprawdź, w czym liczony jest twój timestamp, żeby nie zapisać miliona niepotrzebnych sekund.
Błędy ze strefami czasowymi
Sytuacja 1: Pomieszane strefy czasowe
Kiedy pracujesz z userami z różnych stref, dane mogą się mieszać. Na przykład:
SELECT TIMESTAMP '2023-10-01 10:00:00' AT TIME ZONE 'UTC';
Upewnij się, że dobrze rozumiesz, w jakiej strefie są twoje dane.
Sytuacja 2: Podwójne strefy czasowe
Zapisanie daty z czasem i potem jeszcze raz uwzględnianie strefy — zły pomysł:
SELECT TIMESTAMP '2023-10-01 10:00:00 UTC' AT TIME ZONE 'UTC'; -- Nie rób tak!
To może prowadzić do złych obliczeń.
Rekomendacje jak unikać błędów
Wybieraj odpowiedni typ danych. Jeśli pracujesz z międzynarodowymi danymi czasowymi, używaj TIMESTAMPTZ. Jeśli wystarczy sama data, zostań przy DATE.
Testuj swoje zapytania. Upewnij się, że wyniki są takie, jak oczekujesz, szczególnie jeśli bawisz się przedziałami czasowymi, formatami albo zaokrąglaniem.
Zapisuj dane czasowe w UTC. To najlepszy sposób, żeby uniknąć zamieszania ze strefami czasowymi.
Sprawdzaj formaty. Upewnij się, że format w TO_CHAR() i TO_DATE() pasuje do twoich danych.
Używaj funkcji z głową. Przeczytaj dokładnie dokumentację PostgreSQL o funkcjach czasowych, żeby nie było niespodzianek.
Praca z danymi czasowymi może być trudna, ale z odpowiednim podejściem i uwagą do detali wszystko pójdzie gładko. Daty i czas to ważna część twoich aplikacji, a zapomnieć o nich to jak nie nastawić budzika na poniedziałkowy poranek!
GO TO FULL VERSION