sql >> Database >  >> RDS >> PostgreSQL

Een toekomstige tijd weergeven in PostgreSQL

Het klinkt alsof je een localtime . wilt opslaan met betrekking tot een bepaalde tijdzone. Bewaar in dat geval een timestamp (zonder tijdzone) en de timezone in een aparte kolom.

Stel dat u een gebeurtenis wilt opnemen die op 26 februari 2030 om 10.00 uur in Chicago zal plaatsvinden en dat het om 10.00 uur lokale tijd moet zijn. ongeacht de tijdzoneregel die op die datum van kracht is.

Als de database de tijdstempel zonder tijdzone opslaat:

unutbu=# select '2030-02-26 10:00:00'::timestamp as localtime, 'America/Chicago' AS tzone;
+---------------------+-----------------+
|      localtime      |      tzone      |
+---------------------+-----------------+
| 2030-02-26 10:00:00 | America/Chicago |
+---------------------+-----------------+

Later kunt u de UTC-datum/tijd van het evenement vinden met

unutbu=# select '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2030-02-26 16:00:00 |
+---------------------+

De query retourneert de UTC datetime, 2030-02-26 16:00:00 , wat overeenkomt met 2030-02-26 10:00:00 lokale tijd in Chicago.

AT TIME ZONE gebruiken vertraagt ​​de toepassing van de tijdzoneregels tot wanneer de vraag wordt gemaakt in plaats van wanneer de timestamptz is ingevoegd.

AT TIME ZONE gebruiken op een timestamp lokaliseert de datetime naar de opgegeven tijdzone, maar rapporteert de datetime in de tijdzone van de gebruiker .Gebruik AT TIME ZONE op een timestamptz converteert de datetime naar de opgegeven tijdzone, laat vervolgens de offset vallen, waardoor een timestamp wordt geretourneerd .Boven, AT TIME ZONE wordt twee keer gebruikt:eerst om een ​​timestamp te lokaliseren en vervolgens om de geretourneerde timestamptz . te converteren naar een nieuwe tijdzone (UTC). Het resultaat is een timestamp in UTC.

Hier is een voorbeeld van AT TIME ZONE 's gedrag op timestamp s:

unutbu=# SET timezone = 'America/Chicago';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
|        timezone        |
+------------------------+
| 2030-02-26 10:00:00-06 |
+------------------------+

unutbu=# SET timezone = 'America/Los_Angeles';
unutbu=# SELECT '2030-02-26 10:00:00'::timestamp AT TIME ZONE 'America/Chicago';
+------------------------+
|        timezone        |
+------------------------+
| 2030-02-26 08:00:00-08 |
+------------------------+

2030-02-26 10:00:00-06 en 2030-02-26 08:00:00-08 zijn dezelfde datetimes maar gerapporteerd in verschillende gebruikerstijdzones. Dit toont 10 uur in Chicago is 8 uur in Los Angeles (met huidige tijdzonedefinities):

unutbu=# SELECT '2030-02-26 10:00:00-06'::timestamptz AT TIME ZONE 'America/Los_Angeles';
+---------------------+
|      timezone       |
+---------------------+
| 2030-02-26 08:00:00 |
+---------------------+

Een alternatief voor het gebruik van AT TIME ZONE tweemaal is om de gebruikerstijdzone in te stellen naar UTC . Dan zou je kunnen gebruiken

select localtime AT TIME ZONE tzone

Merk op dat wanneer u dit op deze manier doet, een timestamptz wordt geretourneerd in plaats van een timestamp .

Houd er rekening mee dat het opslaan van lokale tijden problematisch kan zijn omdat er niet-bestaande tijden en onduidelijke tijden kunnen zijn. Bijvoorbeeld, 2018-03-11 02:30:00 is een niet-bestaande lokale tijd in America/Chicago . Postgresql normaliseert niet-bestaande lokale tijden door aan te nemen dat het verwijst naar de overeenkomstige tijd nadat de zomertijd (DST) is begonnen (alsof iemand is vergeten de klok vooruit te zetten):

unutbu=# select '2018-03-11 02:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)

unutbu=# select '2018-03-11 03:30:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-03-11 08:30:00 |
+---------------------+
(1 row)

Een voorbeeld van een ambigue lokale tijd is 2018-11-04 01:00:00 in America/Chicago . Het komt twee keer voor vanwege de DST. Postgresql lost deze dubbelzinnigheid op door een later tijdstip te kiezen, nadat de DST is afgelopen:

unutbu=# select '2018-11-04 01:00:00'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-11-04 07:00:00 |
+---------------------+

Merk op dat dit betekent dat er geen manier is om te verwijzen naar 2018-11-04 06:00:00 UTC door lokale tijden op te slaan in de America/Chicago tijdzone:

unutbu=# select '2018-11-04 00:59:59'::timestamp AT TIME ZONE 'America/Chicago' AT TIME ZONE 'UTC';
+---------------------+
|      timezone       |
+---------------------+
| 2018-11-04 05:59:59 |
+---------------------+


  1. Hoe slechts één kolom van de sql-tabel per csv-bestand bij te werken?

  2. Hoe te controleren of een opgeslagen procedure bestaat voordat u deze maakt?

  3. Selecteer dag van de week vanaf datum

  4. INSERT meerdere vermeldingen van Android -> PHP -> MYSQL