Lokalny CRM - daty ze strefą czasową, czy nie?

Lokalny CRM - daty ze strefą czasową, czy nie?
bbhzp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 107
0

Cześć,
tworzę właśnie średniej wielkości program CRM/ERP (Rest API + frontend). Aplikacja obsługuje jedną firmę (czyli nie SAAS) i ma być hostowana po lokalnej sieci, lub, kiedyś, w Azurze (... albo w innym hostingu).

Czy kolumny przechowujące datę (np. data dodania / edycji, terminy zadań, wystawienia oferty) powinny zawierać w sobie informację o strefie czasowej (... może UTC)? Czy może po prostu przechowywać daty zgodnie z ustawieniami serwera, bez dodatkowych metadanych?

PS: Używam PostgreSQL i waham się między typami timestamp i timestampz.

Z góry dziękuję.

RJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 493
4

Jak masz tylko local time to czym się przejmujesz...
Ja z doświadczenia bym się nie pchal w UTC, tylko Unix Epoch bym używał jeśli już i po stronie klienta parsowal to na local time bez żadnych ceregieli ze stringami 😉

EDIT.
Nie jest to też idealne rozwiązanie bo rozczytywanie po timestampie w formacie liczbowym po stronie bazy jest kaszaniaste i to jest trade off, a że to ERP/CRM to musisz sam podjąć decyzję. Albo UTC na baze, konwersja do longa po stronie API juz na local time czy DateTime lokalny czy long timestamp - Twój wybór 😀

cerrato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 9177
1

Pytanie - skoro będzie tego używać tylko jedna firma, to czy jest ryzyko/opcja/szansa, że będą zapisywane dane z różnych stref czasowych?

Jeśli nie jesteś na 100% pewien że nie pojawią się inne strefy, to może lepiej po stronie aplikacji zrobić jakąś klasę obudowującą czas/jakiś time provider i czas odczytywać/zapisywać w oparciu o nią. W ten sposób z punktu widzenia apki masz jedno źródło czasu, a potem czy ona zamieni UTC na lokalny, doda czas letni albo odejmie godzinę na zimowy itp, to już aplikacji nie interesuje. A ewentualne zmian robisz tylko w jednym miejscu - więc nie ma ryzyka, że coś pochrzanisz, gdzieś zapomnisz zmienić i część zapisów będzie lecieć w UTC, a część w jakimś innym formacie.

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5654
8

o kurde, ja teraz byłem w projekcie gdzie nie zapisywali zony, i system był faktycznie tylko dla jednego słusznego kraju czyli niemców, problem polegał na tym że kupiono systemy dla jakiś innych krajów i dyrekcja postanowiła wyklepać wspólny front dla tych trzech systemów. opczywiście normalne systemy z normalnych krajów używały zony, a system z jedynie słusznego kraju tej zony nie używał. więc na etapie BFF sprawdzaliśmy czy jest zona i czy nie. i według tego dodawaliśmy zonę z jedynie słusznego kraji

Taka zona to 4 bayjty? Co ci szkodzi dodać? najwyżej zaoszczędzisz dużo roboty programistom w przyszłości co będą to integrować z innymi krajami unii

KE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 787
4

Czy może po prostu przechowywać daty zgodnie z ustawieniami serwera

Absolutnie nigdy. Nie powinno cię w ogóle interesować, jaka strefa czasowa jest ustawiona na serwerze. Jak przeniesiesz serwer 5000 km dalej, to zachowanie aplikacji ma się zmienić? Podejrzewam że nie ;)

bbhzp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 107
0

Dziękuję wszystkim za odpowiedzi.

Postanowiłem, że będę przechowywać strefy i czas zapisywać w UTC (czyli w C# DateTime.UtcNow). Tylko skoro czas w bazie będzie UTC, to jak mam interpretować daty przesyłane przez frontend? Dla przykładu, taki <input type="date"> zwraca datę w formacie 2026-01-03. Więc jeśli dostanę takiego JSONa:

Kopiuj
{
  "title": "Testowe zadanie",
  "description": "ukończyć projekt",
  "startDate": "2026-01-03"
}

To skąd mam wiedzieć, w jakiej strefie czasowej znajduje się użytkownik API i (ewentualnie) przekonwertować to na UTC?

PS: Czat podpowiada, że typ Date w JavaScript'cie zawiera w sobie informacje o strefie czasowej i automatycznie je dodaje do http requestów.

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
3
  1. Daty, które Ty tworzysz - czyli wszelkie inserted_at, updated_at, etc. składujesz jako UTC
  2. Daty podane przez użytkownika zazwyczaj składujesz bez strefy czasowej i tak jak są podane.

To jest jedyne praktyczne rozwiązanie tej sprawy.

RJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 493
1

Zawsze możesz nakładać pipe ktory zaaplikuje lokalny timezone dla wyniku. W JS jak tworzysz obiekt new Date() to zawsze brana jest obecnie ustawiona strefa czasowa przeglądarki (stąd moja sugestia z epochem na krawędzi API - klient) 😊. Zawsze możesz też zrobić tak później że jak user będzie chciał do wyświetlania wszystkich dat jakas strefe czasową to możesz mu dać tego wybór i po prostu na loginie zaciągać timezone usera.

bbhzp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 107
0
hauleth napisał(a):
  1. Daty, które Ty tworzysz - czyli wszelkie inserted_at, updated_at, etc. składujesz jako UTC
  2. Daty podane przez użytkownika zazwyczaj składujesz bez strefy czasowej i tak jak są podane.

To jest jedyne praktyczne rozwiązanie tej sprawy.

Dziękuję :)
Czyli, używając postgresql, daty do audytu będą w typie timestampz, a daty typu appointment_start, appointment_end w typie timestamp?

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

Pytanie - skoro będzie tego używać tylko jedna firma, to czy jest ryzyko/opcja/szansa, że będą zapisywane dane z różnych stref czasowych?

Na to pytanie odpowiedź brzmi: TAK, bo strefę czasową zmieniamy co pół roku.

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
0

@bbhzp IMHO najlepiej nie używać timestampz w Postgresie tylko timestamp i w aplikacji ogarniać wszystko. Wtedy aplikacja decyduje czy traktować to jako UTC czy nie.

RJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 493
0

@Azarien: a to ciekawe. Nie zmieniamy strefy tylko mamy DST.

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
2

DST to zmiana strefy - z CET na CEST w przypadku PL

RJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 493
0
rjakubowski napisał(a):

@Azarien: a to ciekawe. Nie zmieniamy strefy tylko mamy DST.

Dobrze wiedzieć 😛

No to UTC baza i serwer wysyła obecna stefe na front. Front wyswietla zgodnie z tym co dostał od serwera. Koniec.

bbhzp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 107
0
hauleth napisał(a):

@bbhzp IMHO najlepiej nie używać timestampz w Postgresie tylko timestamp i w aplikacji ogarniać wszystko. Wtedy aplikacja decyduje czy traktować to jako UTC czy nie.

Dlaczego? Wcześniej używałem SQL Servera, który nie miał typu dla dat ze strefą czasową, a Postgresa dopiero się uczę :)

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
0

Bo Postgres też nie ma typu dla dat ze strefą czasową. timestampz nie przechowuje strefy czasowej a przechowuje czas w UTC i zmienia tylko sposób wyświetlania.

PA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3901
2

SQL server od wersji 2008 obsługuje datetimeoffset więc można w nim przechowywać strefy czasowe

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
2
rjakubowski napisał(a):

@Azarien: a to ciekawe. Nie zmieniamy strefy tylko mamy DST.

Zmieniamy różnicę względem UTC. Na jedno wychodzi jak to nazwiesz.

piotrpo
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3359
2

Nie mam za dużego doświadczenia z aplikacjami działającymi wyłącznie w pojedynczej strefie czasowej, ale też nie wiem dlaczego należałoby z nimi postępować inaczej i dlaczego to inaczej miałoby cokolwiek ułatwić.
Moja prosta rada dotycząca obsługi dat:
Po stronie serwera wszystko powinno chodzić w UTC, lub jako instant uznawany za UTC.
Czas strefowy, to wyłącznie kwestia prezentacji i najlepiej nakładać je po stronie klienta.
Mogą się pojawić jakieś wyjątki od tej reguły, przy obniżonej precyzji. Ale skoro mamy precyzję obniżoną do daty, to nie ma też zwykle znaczenia te kilka godzin.

bbhzp
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 107
1

Postanowiłem końcowo wszystkie daty trzymać ze strefą czasową, w typie timestampz. Bieżącą, ustawianą np. dla kolumn created_at, modified_at, itd. pobieram w UTC (czyli w C# DateTime.UtcNow).

Od użytkowników API wymagam podawania daty razem ze strefą w requestach (co i tak jest domyślne we frameworku frontendowym, którego używam) i awaryjnie jeśli jej nie ma, przyjmuję, że podana data jest w strefie polskiej czyli GMT+1.

Dziękuję wszystkim za merytoryczne odpowiedzi :)

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1132
2
hauleth napisał(a):
  1. Daty, które Ty tworzysz - czyli wszelkie inserted_at, updated_at, etc. składujesz jako UTC

A co jak ktoś ktoś wejdzie na serwer i ustawi sobie z palca albo zrobi to jakiś trigger? Albo ktoś postawi sobię bazę dla testów lokalnie i ustawienia będą nie te co na produkcji? Albo sesja użytkownika ustawi inną strefę czasową? timestampz używa się właśnie po to, żeby się tym nie przejmować. Postgres tak czy owak wszystko normalizuje do UTC pod spodem

Dla mnie timestampz to po prostu timestamp, który jest świadomy tego, że są różne strefy czasowe zapewniający odpowiednie konwersje normalizujące wszystko do UTC.

Jedyne sensowny przypadek użycia czasu lokalnego w bazach danych według mnie to przechowywanie danej informacji z zewnętrznego systemu o której nie wiemy nic oprócz tego, że jest poprawna . Np. samolot wylatuje o 14:43 czasu lokalnego z lotniska A i ląduje o 18:54 w lotnisku B w innej strefie czasowej. Użycie strefy czasowej to konieczność kopania się z DST co może być kłopotliwe. Dla timestampów generowanych przez własny system zawsze używam timestampz

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
0

@slsy nie rozumiem o co chodzi Ci z "wstawi z palca" czy "jakiś trigger". W DB daty, które tworzy system składujesz jako UTC. timestampz IMHO jest błędnie nazwany, bo nie składuje TZ jak nazwa by sugerowała i jeśli nie bawisz się z DB bezpośrednio z palca, to nie ma co się przejmować i lepiej IMHO nie bawić się w timestampz, bo jeszcze się coś zepsuje w konwersji w kliencie.

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1132
1

nie rozumiem o co chodzi Ci z "wstawi z palca" czy "jakiś trigger"

Z palca tj. ktoś się zaloguje do bazy za pomocą jakiegoś klienta i dokona operacji ręcznie bez logiki aplikacji. Trigger to po prostu trigger. Często się robi takie rzeczy jak modified_at pół automatycznie triggerem przy każdym update

bo nie składuje TZ jak nazwa by sugerowała

Zgadzam się, początkowo mi też nie pasowała semantyka tego typu z Z .

bo jeszcze się coś zepsuje w konwersji w kliencie.

Ja po prostu zawsze używam wszędzie informacji o timezonie. Lepiej IMO być przesadnie sprecyzowanym i podawać informację nawet wtedy, gdy wszystkie strony zobowiązały się używać UTC

superdurszlak
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 2024
1

Nawet w obrębie jednej strefy czasowej masz zmiany czasu, jak już ktoś wspomniał. Jak lokalny serwer działa w swojej TZ ale zapiszesz datę i godzinę bez TZ, ale też bez normalizacji (do UTC, Unix epoch, cokolwiek) to co właściwie zapisałeś i skąd będzie wiadomo, co z tym potem zrobić?

Ja raczej bym szedł w timestampz z uwagi na czytelność, unix epoch będzie ok jeśli jesteś OK z nieczytelnymi timestampami w bazie. Normalizacja do UTC może by dała radę, plus ustawienie TZ serwera na UTC (żeby nie było niejednoznaczności), chociaż jak się za dużo przelicza, to potem łatwo się rypnąć i śmiesznie się potem szuka przyczyny problemu, gdy serwer dodał offset dwa razy, a potem frontent dołożył jeszcze od siebie, i tak dalej i tak dalej, a w ogóle to ktoś na komórce ma kalendarz gregoriański i dzieją się śmieszne rzeczy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.