Je ne comprends pas la différence entre ces deux colonnes. L'America/Chicago Timezone est UTC-6, donc je m'attends à renvoyer le même résultat:
select timezone('America/Chicago', '2017-01-01 12:00:00'::TIMESTAMP AT TIME ZONE 'UTC'),
timezone('UTC-6' , '2017-01-01 12:00:00'::TIMESTAMP AT TIME ZONE 'UTC');
Cependant, le résultat est:
2017-01-01 06:00:00 | 2017-01-01 18:00:00
De plus, ce comportement est extrêmement gênant,
SELECT '1:00 -1'::time with time zone AT TIME ZONE '-1';
timezone
-------------
03:00:00+01
Quelqu'un peut-il expliquer cela?
Un nom de temps (((((( Name transporte plus d'informations que l'abréviation ou un simple fuseau horaire - Décalage . 'UTC-6' est une "spécification de fuseau horaire de style POSIX" qui est juste une abréviation plus offset.
le manuel sur Zones de temps :
PostgreSQL vous permet de spécifier des fuseaux horaires sous trois formes différentes:
Un nom de fuseau horaire complet, par exemple
America/New_York
. [...]Une abréviation de fuseau horaire, par exemple
PST
. [...]En plus des noms de fuseau horaire et des abréviations, PostgreSQL acceptera les spécifications de fuseau horaire de style POSIX du formulaire
STDoffset
ouSTDoffsetDST
, oùSTD
est une abréviation de zone, le décalage est un numériqueoffset
en heures à l'ouest de UTC, etDST
est une abréviation de zone d'épargne d'été en option, supposée être comprise pendant une heure avant le décalage donné.
La différence que vous observez des tiges d'une autre bizarrerie. Vous devez utiliser +
au lieu de -
:
timezone('UTC+6', '2017-01-01 12:00:00'::TIMESTAMP AT TIME ZONE 'UTC')
Un autre problème à garder à l'esprit est que, dans les noms de zone temporelle POSIX, des compensations positives sont utilisées pour des emplacements OUEST de Greenwich. Partout ailleurs, PostgreSQL suit la Convention ISO-8601 selon laquelle les décalages positifs de Timezone sont positifs Est de Greenwich.
Cependant, même après avoir fixé l'erreur de décalage, les deux expressions sont toujours pas équivalentes . Entre autres choses, un nom de fuseau horaire comme 'America/Chicago' considère également les règles de l'heure d'été (DST).
BTW, votre expression peut être simplifiée pour:
timestamptz '2017-01-01 12:00:00 +0' AT TIME ZONE 'UTC+6'
Mais vous voulez probablement le nom du fuseau horaire pour être sûr:
timestamptz '2017-01-01 12:00:00 +0' AT TIME ZONE 'America/Chicago'
En rapport:
Pour résoudre Votre deuxième exemple:
SELECT '1:00 -1'::time with time zone AT TIME ZONE '-1';
Syntaxe simplifiée et équivalente:
SELECT timetz '1:00 -1' AT TIME ZONE '-1';
Les deux instances du littéral -1
ont différent signification . Le premier décalage fait partie du littéral *timetz*
indiquant un emplacement ( Est de Greenwich (conforme à la norme SQL). Le second est un Spécifications du fuseau horaire de style POSIX signifiant un décalage (( Ouest de Greenwich. En l'absence d'une spécification de zone, UTC est supposé comme base. Voir:
Notez également que le AT TIME ZONE
construire renvoie timetz
pour timetz
entrée. Il suffit de re-basse le temps littéral sur un décalage différent. Ceci est différent de son utilisation avec timestamp
/timestamptz
entrée, où le type de données est également commuté.
Mais n'utilisez pas le type de données timetz
(time with time zone
) du tout . Il est cassé par la conception et seulement inclus dans Postgres, car cela fait partie de SQL standard. Il est utilisé explicitement découragé. Voir: