Er zijn hier geen kogelvrije oplossingen.
Mijn eerste advies:vertrouw nooit op de standaard tijdzone van de server.
Mijn tweede advies:kies tussen timestamp
-timestamptz
volgens de (overheersende) semantiek van de gegevens.
Meer in detail:PostgresSQL heeft twee tijdstempelvarianten, met de verwarrende naam TIMESTAMP WITHOUT TIMEZONE (timestamp)
en TIMESTAMP WITH TIMEZONE (timestamptz)
. Eigenlijk geen van beide slaat een tijdzone op, zelfs geen offset. Beide datatypes nemen dezelfde breedte in (4 bytes), en hun verschil is subtiel - en, erger nog, kan je bijten als je ze niet volledig begrijpt en je server de tijdzone verandert. Mijn gezond verstand regelset is:
-
Gebruik
TIMESTAMP WITH TIMEZONE (timestamptz)
voor het opslaan van gebeurtenissen die voornamelijk verband houden met de "fysieke" tijd , waarvoor u vooral geïnteresseerd bent in de vraag ofevent 1
was voorevent 2
(ongeacht de tijdzones), of het berekenen van tijdsintervallen (in "fysieke eenheden", bijv. seconden; niet in "civiele" eenheden als dagen-maanden, enz.). Het typische voorbeeld is de tijd voor het maken/wijzigen van records - wat men gewoonlijk bedoelt met het woord "Tijdstempel ". -
Gebruik
TIMESTAMP WITHOUT TIMEZONE (timestamp)
voor het opslaan van evenementen waarvoor de relevante informatie de "burgerlijke tijd" . is (dat wil zeggen, de velden{year-month-day hour-min-sec}
als geheel), en de query's hebben betrekking op kalenderberekeningen. In dit geval zou u hier alleen de "lokale tijd" opslaan, d.w.z. de datum-tijd ten opzichte van een niet-gespecificeerde (irrelevante, of impliciete, of ergens anders opgeslagen) tijdzone.
De tweede optie maakt het eenvoudiger om te zoeken naar bijvoorbeeld "alle gebeurtenissen die plaatsvonden op dag '2013-01-20'" (in elke corresponderende regio/land/tijdzone) - maar maakt het moeilijker om te zoeken naar "alle gebeurtenissen die heeft plaatsgevonden (fysiek) vóór een referentiegebeurtenis" (tenzij we weten dat ze zich in dezelfde tijdzone bevinden). Jij kiest.
Als je het volledige ding nodig hebt, is geen van beide genoeg, je moet de tijdzone of de offset in een extra veld opslaan. Een andere optie, die een paar bytes verspilt, maar efficiënter kan zijn voor zoekopdrachten, is om beide velden op te slaan.
Zie ook dit antwoord .