sql >> Database >  >> RDS >> PostgreSQL

Krijg tijd met tijdzone van tijd zonder tijdzone en de naam van de tijdzone

WAARSCHUWING:PostgreSQL newbie (zie opmerkingen over de vraag!). Ik weet echter een beetje van tijdzones, dus ik weet wat zinnig is vragen.

Het lijkt mij dat dit in feite een niet-ondersteunde situatie is (helaas) als het gaat om AT TIME ZONE . Kijkend naar de AT TIME ZONE documentatie geeft het een tabel waar de "invoer" waardetypes alleen zijn:

  • tijdstempel zonder tijdzone
  • tijdstempel met tijdzone
  • tijd met tijdzone

We missen degene die je wilt:tijd zonder tijdzone. Wat je vraagt ​​is enigszins logisch, hoewel het wel van de datum afhangt... aangezien verschillende tijdzones verschillende verschuivingen kunnen hebben, afhankelijk van de datum. Bijvoorbeeld 12:00:00 Europe/London may bedoel 12:00:00 UTC, of ​​het kan 11:00:00 UTC betekenen, afhankelijk van of het winter of zomer is.

Op mijn systeem, nadat ik de systeemtijdzone had ingesteld op Amerika/Regina, de vraag

SELECT ('2011-11-22T12:00:00'::TIMESTAMP WITHOUT TIME ZONE) 
                               AT TIME ZONE 'America/Vancouver'

geeft me 2011-11-22 14:00:00-06 als resultaat. Dat is niet ideaal , maar het geeft op zijn minst het moment in de tijd (denk ik). Ik geloof dat als je dat ophaalt met een clientbibliotheek - of het vergelijkt met een andere TIMESTAMP WITH TIME ZONE - je zou het juiste resultaat krijgen. Het is alleen de tekstconversie die vervolgens het systeem gebruikt tijdzone voor uitvoer.

Zou dat goed genoeg voor je zijn? Kun je je SCHEDULES.time . wijzigen? veld om een ​​TIMESTAMP WITHOUT TIME ZONE . te zijn veld, of (tijdens de zoekopdracht) de tijd uit het veld combineren met een datum om een ​​tijdstempel zonder tijdzone te maken?

EDIT:Als je tevreden bent met de "huidige datum" ziet het eruit alsof je je zoekopdracht gewoon kunt veranderen in:

SELECT (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Natuurlijk, het huidige systeem datum is mogelijk niet hetzelfde als de huidige datum in de lokale tijdzone . Ik denk dit zal dat deel repareren...

SELECT ((current_timestamp AT TIME ZONE USERS.tz)::DATE + schedules.time)
       AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Met andere woorden:

  • Neem het huidige moment
  • Bereken de lokale datum/tijd in de tijdzone van de gebruiker
  • Pak de datum daarvan
  • Voeg de geplande tijd toe aan die datum om een ​​TIMESTAMP WITHOUT TIME ZONE te krijgen
  • Gebruik AT TIME ZONE om de tijdzone toe te passen op die lokale datum/tijd

Ik weet zeker dat er een betere manier is, maar ik denk het is logisch.

Houd er rekening mee dat dit in sommige gevallen kan mislukken:

  • Wat wil je dat het resultaat is voor een tijd van 01:30 op een dag waarop de klok verspringt van 01:00 naar 02:00, dus 01:30 komt helemaal niet voor?
  • Wat wil je dat het resultaat is voor een tijd van 01:30 op een dag dat de klok teruggaat van 02:00 naar 01:00, dus 01:30 komt twee keer voor?


  1. Een standaard datumnotatie instellen op PostgreSQL

  2. Hoe een datum van mySQL te vergelijken met de huidige datum in Java?

  3. Hoe een tabel exporteren als CSV met koppen op Postgresql?

  4. Hoe een php-array te maken en te vullen vanuit de Mysql-database