Le temps et PostgreSQL

A force d’utiliser PHP couplé à PostgreSQL, une mauvaise habitude s’est installée : les colonnes censées représenter un timestamp sont systématiquement déclarée TIMESTAMP WITHOUT TIME ZONE, tout simplement parce qu’avec un serveur configuré avec une TimeZone ‘Europe/Paris’ (CEST), celà reste très simple à récupérer depuis PHP pour représenter un horaire légal français.

Celà dit, çà commence à se compliquer quand la donnée doit représenter un horodatage en dehors de la France métropolitaine, et surtout si dans la même table des données horodatées sont censées concerner des lieux différents …

Soit, gardons les timestamps without time zone, et voyons ce que l’on peut en faire !

Un SELECT '2017-04-25 10:00'::TIMESTAMP WITHOUT TIME ZONE retourne 2017-04-25 10:00:00 et cet horaire est exprimé dans le fuseau horaire du serveur (ou de la variable d’environnement TZ) ; dans le même ordre d’idée un SELECT CURRENT_TIMESTAMP::TIMESTAMP WITHOUT TIME ZONE retournera les date et heure courantes.

Maintenant, si on veut connaître l’heure courante à la Réunion, par exemple, située dans le fuseau horaire GMT+4 (on peut aussi utiliser la timezone RET) il est possible de demander à PostgreSQL de convertir ce timestamp avec la construction SQL standard AT TIME ZONE :

SELECT '2017-04-25 10:00'::TIMESTAMP WITHOUT TIME ZONE AT TIME ZONE 'RET'

mais, dans ce cas la réponse fournie est « 2017-04-25 08:00:00+02 » : on demande de convertir une heure exprimée en heure légale française (GMT+2 en horaire d’été) vers du GMT+4 et on obtient 2 heures de moins !!!

De fait, le problème est dû au manque de la zone dans le timestamp initial, et pour corriger il faudrait l’exprimer :

SELECT '2017-04-25 10:00'::TIMESTAMP WITH TIME ZONE AT TIME ZONE 'RET' qui retourne bien la bonne date : « 2017-04-25 12:00:00 ».

Donc, si dans une table on veut transformer un timestamp sans la zone vers une zone différente, il faudra bien penser à caster :

(temps::TIMESTAMP WITH TIME ZONE AT TIME ZONE 'RET')::TIMESTAMP WITHOUT TIME ZONE

pour avoir un résultat cohérent.

posté le 25. avril 2017 à 1:18 par info · Permalink
Catégories : postgresql

Ajoutez un commentaire