sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL dato() med tidszone

Grundlæggende er det, du ønsker:

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

Jeg fik løsningen fra denne artikel er nedenfor, som er lige GULD!!! Det forklarer dette ikke-trivielle problem meget tydeligt, læs det, hvis du ønsker at forstå pstgrsql TZ-styring bedre.

Udtrykke PostgreSQL-tidsstempler uden zoner i lokal tid

Her er hvad der foregår. Først skal du vide, at 'PST-tidszonen er 8 timer efter UTC-tidszonen, så for eksempel 1. januar 2014, 16:30 PST (ons, 01. jan. 2014 16:00:30 -0800) svarer til 2. januar 2014, 00:30 AM UTC (tors, 02. jan. 2014 00:00:30 +0000). Ethvert tidspunkt efter kl. 16.00 i PST glider over til næste dag, fortolket som UTC.

Som Erwin Brandstetter nævnte ovenfor, har postresql to typer tidsstempler datatyper, en med en tidszone og en uden. Hvis dine tidsstempler inkluderer en tidszone, så en simpel:

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

vil arbejde. Men hvis dit tidsstempel er tidszoneløst, vil udførelse af ovenstående kommando ikke virke, og du skal FØRST konvertere dit tidszoneløse tidsstempel til et tidsstempel med en tidszone, nemlig en UTC-tidszone, og KUN SÅ konvertere det til din ønskede 'PST' eller 'US/ Pacific' (som er de samme op til nogle sommertidsproblemer. Jeg synes, du skal have det fint med begge dele).

Lad mig demonstrere med et eksempel, hvor jeg opretter et tidszoneløst tidsstempel. Lad os for nemheds skyld antage, at vores lokale tidszone faktisk er 'PST' (hvis det ikke var, så bliver det en lille smule mere kompliceret, hvilket er unødvendigt i forbindelse med denne forklaring).

Sig, at jeg har:

$ 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

Dette vil give:

"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"

Det sidste tidsstempel er årsagen til al forvirringen vedrørende konvertering af tidszoneløst tidsstempel fra UTC til 'PST' i postgresql. Når vi skriver:

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

Vi tager et tidszoneløst tidsstempel og forsøger at konvertere det til 'PST TZ (vi antager indirekte, at postgresql vil forstå, at vi vil have det til at konvertere tidsstemplet fra en UTC TZ, men postresql har sine egne planer!). I praksis er det, postgresql gør, at det tager det tidszoneløse tidsstempel ('2014-01-2 00:30:00) og behandler det, som om det ALLEREDE VAR et 'PST' TZ-tidsstempel (dvs.:2014-01-2 00:30 :00 -0800) og konverterer det til UTC tidszone!!! Så det skubber det faktisk 8 timer frem i stedet for tilbage! Således får vi (2014-01-02 08:30:00+00).

I hvert fald er denne sidste (uintuitive) adfærd årsagen til al forvirring. Læs artiklen, hvis du vil have en mere grundig forklaring, jeg fik faktisk resultater, som er lidt anderledes end deres på denne sidste del, men den generelle idé er den samme.



  1. Hvorfor oracle IN-klausul kun har en grænse på 1000 for statiske data?

  2. MySQL-udløser ved Indsæt/Opdater begivenheder

  3. SQL Server på Linux

  4. SQLskills Wait Types Library viser nu SentryOne-data