Det finns inga skottsäkra lösningar här.
Mitt första råd:lita aldrig på serverns standardtidszon.
Mitt andra råd:välj mellan timestamp
-timestamptz
enligt datas (dominerande) semantik.
Mer detaljerat:PostgresSQL har två tidsstämpelvarianter, förvirrande namnet TIMESTAMP WITHOUT TIMEZONE (timestamp)
och TIMESTAMP WITH TIMEZONE (timestamptz)
. Faktiskt inte heller lagrar en tidszon, inte ens en offset. Båda datatyperna upptar samma bredd (4 byte), och deras skillnad är subtil - och, värre, kan bita dig om du inte helt förstår dem och din server ändrar tidszonen. Mitt förnuftsregler är:
-
Använd
TIMESTAMP WITH TIMEZONE (timestamptz)
för att lagra händelser som huvudsakligen är relaterade till den "fysiska" tiden , för vilken du främst är intresserad av att fråga omevent 1
var föreevent 2
(oavsett tidszoner), eller beräkningstidsintervall (i "fysiska enheter", t.ex. sekunder, inte i "civila" enheter som dagar-månader, etc). Det typiska exemplet är tidpunkt för skapande/ändring av post - vad man vanligtvis menar med ordet "Timestamp ". -
Använd
TIMESTAMP WITHOUT TIMEZONE (timestamp)
för lagring av händelser där den relevanta informationen är "borgerlig tid" (det vill säga fälten{year-month-day hour-min-sec}
som helhet), och frågorna involverar kalenderberäkningar. I det här fallet skulle du bara lagra den "lokala tiden", dvs. datum-tid i förhållande till någon ospecificerad (irrelevant, eller underförstådd, eller lagrad någon annanstans) tidszon.
Det andra alternativet gör det lättare att fråga efter t.ex. "alla händelser som hände på dagen '2013-01-20'" (i varje motsvarande region/land/tidszon) - men gör det svårare att fråga efter "alla händelser som inträffade (fysiskt) före en referenshändelse" (om vi inte vet att de är i samma tidszon). Du väljer.
Om du behöver hela grejen räcker inget av det, du måste antingen lagra tidszonen eller offset i ett extra fält. Ett annat alternativ, som slösar bort några byte men kan vara mer effektivt för frågor är att lagra båda fälten.
Se även det här svaret .