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

Få tid med tidszone fra tid uden tidszone og tidszonenavnet

ADVARSEL:PostgreSQL newbie (se kommentarer til spørgsmålet!). Jeg ved dog lidt om tidszoner, så jeg ved, hvad der giver mening at spørge.

Det ser for mig ud som om, at dette dybest set er en ikke-understøttet situation (desværre), når det kommer til AT TIME ZONE . Ser på AT TIME ZONE dokumentation det giver en tabel, hvor "input" værdityperne kun er:

  • tidsstempel uden tidszone
  • tidsstempel med tidszone
  • tid med tidszone

Vi mangler den, du ønsker:tid uden tidszone. Det, du spørger om, er noget logisk, selvom det afhænger af datoen... da forskellige tidszoner kan have forskellige forskydninger afhængigt af datoen. For eksempel 12:00:00 Europa/London maj betyder 12:00:00 UTC, eller det kan betyde 11:00:00 UTC, afhængigt af om det er vinter eller sommer.

På mit system, efter at have indstillet systemets tidszone til America/Regina, er forespørgslen

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

giver mig 2011-11-22 14:00:00-06 som resultat. Det er ikke ideelt , men det giver i det mindste det øjeblikkelige tidspunkt (tror jeg). Jeg tror, ​​at hvis du hentede det med et klientbibliotek - eller sammenlignede det med et andet TIMESTAMP WITH TIME ZONE - du ville få det rigtige resultat. Det er kun tekstkonverteringen, der så bruger systemet tidszone for output.

Ville det være godt nok for dig? Kan du enten ændre din SCHEDULES.time felt til at være et TIMESTAMP WITHOUT TIME ZONE felt, eller (på forespørgselstidspunktet) kombinere tiden fra feltet med en dato for at oprette et tidsstempel uden tidszone?

EDIT:Hvis du er tilfreds med den "aktuelle dato", ser den ud ligesom du bare kan ændre din forespørgsel til:

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

Selvfølgelig, det nuværende system datoen er muligvis ikke den samme som den aktuelle dato i den lokale tidszone . Jeg tror dette vil rette den del...

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

Med andre ord:

  • Tag det aktuelle øjeblik
  • Beregn den lokale dato/tid i brugerens tidszone
  • Tag datoen for det
  • Føj tidsplanen til den dato for at få et TIMESTAMP WITHOUT TIME ZONE
  • Brug AT TIME ZONE for at anvende tidszonen på den lokale dato/tid

Jeg er sikker på, at der er en bedre måde, men jeg tror det giver mening.

Du skal dog være opmærksom på, at dette i nogle tilfælde kan mislykkes:

  • Hvad vil du have, at resultatet skal være for et tidspunkt på 01:30 på en dag, hvor uret springer fra 01:00 til 02:00, så 01:30 overhovedet ikke forekommer?
  • Hvad vil du have, at resultatet skal være for en tid på 01:30 på en dag, hvor uret går tilbage fra 02:00 til 01:00, så 01:30 forekommer to gange?


  1. Hvordan kan jeg simulere en array-variabel i MySQL?

  2. Hvorfor kalder PostgreSQL min STABLE/IMMUTABLE funktion flere gange?

  3. Hvordan sender man sqlparameter til IN()?

  4. MySql giver brugertilladelse