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.