web-dev-qa-db-fra.com

Le fuseau horaire de PostgreSQL ne correspond pas au fuseau horaire du système

J'ai plusieurs installations PostgreSQL 9.2 où le fuseau horaire utilisé par PostgreSQL est GMT, bien que l'ensemble du système soit "Europe/Vienne". J'ai revérifié que postgresql.conf ne pas contient le paramètre timezone, donc selon la documentation, il devrait revenir au fuseau horaire du système.

Cependant,

# su -s /bin/bash postgres -c "psql mydb"

mydb=# show timezone;
 TimeZone 
----------
 GMT
(1 row)

mydb=# select now();
              now              
-------------------------------
 2013-11-12 08:14:21.697622+00
(1 row)

Des indices, d'où le fuseau horaire GMT pourrait provenir? L'utilisateur système n'a pas TZ défini et le /etc/timezone et /etc/timeinfo semble être configuré correctement.

# cat /etc/timezone 
Europe/Vienna
# date
Tue Nov 12 09:15:42 CET 2013

Tous les indices sont appréciés, merci d'avance!

18
Martin C.

La valeur par défaut du paramètre TimeZone a changé dans la version 9.2:

(..) Si elle n'est pas définie explicitement, le serveur initialise cette variable au fuseau horaire spécifié par son environnement système. (...)

(...) La valeur par défaut intégrée est GMT, mais elle est généralement remplacée dans postgresql.conf; initdb y installera un paramètre correspondant à son environnement système. (...)

Ce qui signifie qu'avant la version 9.2, la valeur par défaut à postgresql.conf doit être défini pendant la phase initdb. Si vous avez remplacé cette valeur (probablement en copiant l'ancien postgresql.conf lors de la mise à niveau à partir d'anciennes versions) PostgreSQL utilise la valeur "GMT" par défaut.

La solution pour votre cas est assez simple, il suffit de modifier le paramètre TimeZone sur postgresql.conf à la valeur souhaitée:

TimeZone = 'Europe/Vienna'

Après cela, vous devez reload le service:

# su - postgres -c "psql mydb -c 'SELECT pg_reload_conf()'"

Ensuite, tous les champs stockés sous la forme timestamp with time zone (ou timestamptz) s'affichera désormais correctement. Mais vous devrez corriger à la main tous (mettre à jour) les champs stockés comme timestamp without time zone (ou timestamp).

Un conseil que je donne à tous ceux qui mettent à niveau PostgreSQL est de ne pas copier l'ancien postgresql.conf au nouveau cluster (remarquez que je ne suis pas sûr si c'est ce que vous avez fait, mais j'ai vu ce même problème beaucoup à cause de cela). Obtenez simplement celui généré par initdb et ajoutez les modifications (un outil diff peut être utile pour cette tâche).

25
MatheusOl

J'ai trouvé une solution pour cela.

il suffit de créer un lien symbolique à l'intérieur / usr/share/zoneinfo / nommé localtime (ou quel que soit le nom que vous souhaitez) pour pointer vers / etc/localtime

/usr/share/zoneinfo/localtime -> /etc/localtime

de cette façon, vous créez une chaîne de liens qui pointe finalement vers le fuseau horaire de votre système.

/etc/localtime -> /usr/share/zoneinfo/America/Los_Angeles

Prenez maintenant le nom du lien que vous avez créé (heure locale dans mon cas) et utilisez-le comme valeur de l'élément de configuration dans postgresql.conf

TimeZone = 'localtime'

redémarrez postgresql et vérifiez l'heure avec "SELECT now ();" et "afficher le fuseau horaire";

0
MatteoBee