programowanieBackend developer, analityk BI

Wyjaśnij, jak przetwarzać dane czasowe i przedziały dat w SQL, jakie są cechy funkcji pracy z czasem (DATEDIFF, DATEADD, INTERVAL) w różnych DBMS? Jakie pułapki mogą wystąpić podczas pracy z strefami czasowymi? Podaj przykład poprawnego obliczenia różnicy czasowej.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W SQL istnieje duża liczba funkcji do pracy z datami i przedziałami: DATEDIFF, DATEADD (T-SQL), praca z typem INTERVAL (PostgreSQL), funkcjonalność do przekształcania czasów w różne strefy (AT TIME ZONE). Aby poprawnie pracować z datami, kluczowe jest stosowanie typów danych z uwzględnieniem strefy czasowej (TIMESTAMP WITH TIME ZONE, timestamptz), a nie tylko DATE lub DATETIME, szczególnie dla globalnych usług.

W różnych DBMS składnia i cechy pracy różnią się:

  • SQL Server: DATEDIFF, DATEADD, FORMAT, ale brak pełnoprawnego INTERVAL. Strefy czasowe są regulowane jawnie.
  • PostgreSQL: wsparcie dla INTERVAL, wiele funkcji (+/- INTERVAL), bezpośrednie zarządzanie strefami czasowymi.

Błędy często występują z powodu niespójności w przechowywaniu w UTC/lokalnym czasie i mieszania operacji, które nie uwzględniają różnicy.

Przykład obliczenia różnicy (PostgreSQL)

SELECT EXTRACT(EPOCH FROM (event_end AT TIME ZONE 'UTC' - event_start AT TIME ZONE 'UTC')) / 3600 AS hours FROM events

Pytanie z pułapką

Czy różnica dat w DATEDIFF może dać liczbę ujemną, i co oznacza ich kolejność?

Odpowiedź: Tak, DATEDIFF (DATEDIFF(day, d1, d2)) zwraca liczbę ujemną, jeśli d2 < d1. Ważne jest, aby nie pomylić kolejności parametrów: najpierw idzie jednostka miary, potem data początkowa, potem końcowa.

Przykład:

SELECT DATEDIFF(day, '2024-05-01', '2024-04-25') -- zwróci -6

Przykłady rzeczywistych błędów


Historia

W projekcie z globalnymi użytkownikami raporty były generowane w lokalnym czasie serwerów w każdym regionie. Efekt — rozjeżdżające się agregaty po datach i pojawienie się "dziur" na granicy dni dla użytkowników z innych stref czasowych. Naprawione przez przekształcenie wszystkich danych czasowych na UTC i przeliczenie tylko do wyświetlenia.


Historia

Podczas obliczania długości subskrypcji przez DATEDIFF pomylono kolejność dat. W rezultacie niektórych użytkowników błędnie uznano za "superużytkowników" z założoną negatywną datą. Naprawiono wprowadzeniem sprawdzenia kolejności dat.


Historia

Programista przechowywał DATETIME bez uwzględnienia strefy czasowej, przy migracji do PostgreSQL wartości zostały zinterpretowane jako UTC, podczas gdy pierwotnie były w GMT+3, co spowodowało przesunięcie zdarzeń w raportach o 3 godziny wstecz. Wniosek — zawsze przechowywać i przekształcać daty z uwzględnieniem strefy!