sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL date() met tijdzone

Wat je eigenlijk wilt is:

$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40

Ik heb de oplossing van dit artikel hieronder, dat is rechtstreeks GOUD !!! Het legt dit niet-triviale probleem heel duidelijk uit, lees het als je pstgrsql TZ-beheer beter wilt begrijpen.

PostgreSQL-tijdstempels uitdrukken zonder zones in lokale tijd

Hier is wat er aan de hand is. Eerst moet u weten dat 'PST-tijdzone 8 uur achter UTC-tijdzone ligt, dus bijvoorbeeld 1 januari 2014, 16:30 PST (wo, 01 januari 2014 16:00:30 -0800) is gelijk aan 2 januari 2014, 00:30 AM UTC (do, 02 jan 2014 00:00:30 +0000). Elk moment na 16:00 uur in PST schuift over naar de volgende dag, geïnterpreteerd als UTC.

Ook, zoals Erwin Brandstetter hierboven vermeldde, heeft postresql twee soorten tijdstempels, een met een tijdzone en een zonder. Als uw tijdstempels een tijdzone bevatten, dan is een eenvoudige:

$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40

zal werken. Als uw tijdstempel echter tijdzoneloos is, zal het uitvoeren van de bovenstaande opdracht niet werken en moet u EERST uw tijdzoneloze tijdstempel converteren naar een tijdstempel met een tijdzone, namelijk een UTC-tijdzone, en ALLEEN DAARNA converteren naar uw gewenste 'PST' of 'US/ Pacific' (die hetzelfde zijn tot wat zomertijdproblemen. Ik denk dat je met beide wel in orde zou moeten zijn).

Laat me demonstreren met een voorbeeld waarin ik een tijdzoneloze tijdstempel maak. Laten we voor het gemak aannemen dat onze lokale tijdzone inderdaad 'PST' is (zo niet, dan wordt het een klein beetje ingewikkelder, wat niet nodig is voor het doel van deze uitleg).

Stel dat ik heb:

$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b,  timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Dit levert:

"a"=>"2014-01-02 00:30:00"   (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"

De laatste tijdstempel is de reden voor alle verwarring over het omzetten van tijdzoneloze tijdstempels van UTC naar 'PST' in postgresql. Wanneer we schrijven:

timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

We nemen een tijdstempel zonder tijdzone en proberen deze te converteren naar 'PST TZ (we gaan er indirect van uit dat postgresql zal begrijpen dat we willen dat het de tijdstempel van een UTC TZ converteert, maar postresql heeft zijn eigen plannen!). In de praktijk, wat postgresql doet, is dat het de tijdzoneloze tijdstempel ('2014-01-2 00:30:00) neemt en deze behandelt alsof het REEDS een 'PST' TZ-tijdstempel was (d.w.z.:2014-01-2 00:30 :00 -0800) en converteert dat naar UTC-tijdzone!!! Dus het duwt het eigenlijk 8 uur vooruit in plaats van terug! Zo krijgen we (2014-01-02 08:30:00+00).

Hoe dan ook, dit laatste (niet-intuïtieve) gedrag is de oorzaak van alle verwarring. Lees het artikel als je een meer grondige uitleg wilt, ik kreeg eigenlijk resultaten die een beetje anders zijn dan die van dit laatste deel, maar het algemene idee is hetzelfde.



  1. ODBC-toepassingen verbinden met MySQL

  2. Programmatisch een database maken in SQL Server

  3. Hoe de functie StRFtime() werkt in SQLite

  4. DevOps-overwegingen voor productieklare database-implementaties