L'heure actuelle à Los Angeles est 18h05. Mais quand je cours TZ=UTC-8 date --iso=ns
, je reçois:
2013-12-07T10:05:37,788173835+0800
L'utilitaire de date me dit que l'heure est 10h05 et dit même qu'il le signale en UTC + 8. Pourquoi?
L'heure actuelle à Los Angeles est 18h05. Mais quand je cours TZ=UTC-8 date --iso=ns
, je reçois:
2013-12-07T10:05:37,788173835+0800
L'utilitaire de date me dit que l'heure est 10h05 et dit même qu'il le signale en UTC + 8. Pourquoi?
Réponses:
La raison en est qu'il TZ=UTC-8
est interprété comme un fuseau horaire POSIX . Dans le format de fuseau horaire POSIX, les 3 lettres sont l'abréviation du fuseau horaire (qui est arbitraire) et le nombre est le nombre d'heures que le fuseau horaire est derrière UTC. Signifie donc UTC-8
un fuseau horaire abrégé "UTC" qui est à -8 heures de retard sur le UTC réel, ou UTC + 8 heures.
(Cela fonctionne de cette façon car Unix a été développé aux États-Unis, derrière l'UTC. Ce format permet aux fuseaux horaires américains d'être représentés sous la forme EST5, CST6, etc.)
Vous pouvez voir ce qui se passe par ces exemples:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
Le -0800
format de fuseau horaire ISO adopte l'approche inverse, en -
indiquant que la zone est derrière UTC et en +
indiquant que la zone est en avance sur UTC.
TZ=America/Los_Angeles
. Vous oubliez que l'heure du Pacifique est de -7 pendant l'heure d'été.
TZ=:America/Los_Angeles
. Les deux points indiquent qu'il s'agit d'un fichier de fuseau horaire Olson. Et dans un autre commentaire, il a mentionné qu'il voulait ignorer l'heure d'été, ce que cela ne ferait pas.
EST-5
CST-6
.
Chaque fois que vous spécifiez un fuseau horaire au format +/- 00:00, vous spécifiez un décalage , pas le fuseau horaire réel. De la GNU libc
documentation (qui suit la norme POSIX):
Le décalage spécifie la valeur de temps que vous devez ajouter à l'heure locale pour obtenir une valeur de temps universel coordonné. Il a une syntaxe comme [+ | -] hh [: mm [: ss]]. Ceci est positif si le fuseau horaire local est à l'ouest du méridien principal et négatif s'il est à l'est. L'heure doit être comprise entre 0 et 23, et les minutes et secondes entre 0 et 59.
C'est pourquoi cela semble être l'inverse de ce que vous attendez.
Why?
Parce que POSIX l'exige .
S'il est précédé d'un «-», le fuseau horaire doit être à l'est du premier méridien; sinon, il doit être ouest (ce qui peut être indiqué par un «+» précédent facultatif).
Ainsi, cela donnera l'heure près de [1] Los Angeles
(avec n'importe quelle étiquette de 3 lettres pour le texte du fuseau horaire):
$ TZ=ANY8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 10:47:12 ANY-0800
$ TZ=GMT+8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 10:47:12 GMT-0800
Et cela devrait donner le temps proche Shanghai, China
ou Perth, Australia
:
$ TZ=ANY-8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-24 02:47:12 ANY+0800
$ TZ=CST-8 date "+%Y-%m-%d %H:%M:%S %Z%z"
2016-04-23 02:47:12 CST+0800
[1] Proche car il peut y avoir un DST (Daylight Saving Time) en effet qui décale l'heure locale réelle.
Comme méthode alternative, vous pouvez utiliser la commande zdump
pour afficher l'heure actuelle dans d'autres fuseaux horaires + décalages.
Zdump imprime l'heure actuelle dans chaque nom de zone nommé sur la ligne de commande.
Les mêmes règles s'appliquent aux fuseaux horaires; à l'ouest du méridien principal étant "derrière" tandis qu'à l'est étant "devant".
$ zdump PST PST sam 7 déc 03:25:27 2013 PST
J'ai créé ce script pour afficher plusieurs fuseaux horaires + décalages que nous souhaitons utiliser zdump
et date
pour pouvoir les comparer.
$ cat cmd.bash
#!/bin/bash
printf "\ndate: %s\n\n" "$(date)"
for tz in EST PST PST+8 PST-8 UTC UTC+8 UTC-8; do
echo "-- timezone $tz"
printf "zdump: %s\n" "$(zdump $tz)"
printf "date: %s\n" "$(TZ=$tz date +'%a %b %d %T %Y - (%Z %z)')"
echo ""
done
Ensuite, lorsque vous l'exécutez, vous pouvez voir la comparaison de zdump
à date
:
$ ./cmd.bash
date: Sat Dec 7 02:59:05 EST 2013
-- timezone EST
zdump: EST Sat Dec 7 02:59:05 2013 EST
date: Sat Dec 07 02:59:05 2013 - (EST -0500)
-- timezone PST
zdump: PST Sat Dec 7 07:59:05 2013 PST
date: Sat Dec 07 07:59:05 2013 - (PST +0000)
-- timezone PST+8
zdump: PST+8 Fri Dec 6 23:59:05 2013 PST
date: Fri Dec 06 23:59:05 2013 - (PST -0800)
-- timezone PST-8
zdump: PST-8 Sat Dec 7 15:59:05 2013 PST
date: Sat Dec 07 15:59:05 2013 - (PST +0800)
-- timezone UTC
zdump: UTC Sat Dec 7 07:59:05 2013 UTC
date: Sat Dec 07 07:59:05 2013 - (UTC +0000)
-- timezone UTC+8
zdump: UTC+8 Fri Dec 6 23:59:05 2013 UTC
date: Fri Dec 06 23:59:05 2013 - (UTC -0800)
-- timezone UTC-8
zdump: UTC-8 Sat Dec 7 15:59:05 2013 UTC
date: Sat Dec 07 15:59:05 2013 - (UTC +0800)
TZ=PST+8 date
. Merci. J'ai également trouvé cette explication sousman timezone
: "La chaîne std spécifie le nom du fuseau horaire et doit comporter au moins trois caractères alphabétiques. La chaîne de décalage suit immédiatement std et spécifie la valeur d'heure à ajouter à l'heure locale pour obtenir le temps universel coordonné ( UTC). Le décalage est positif si le fuseau horaire local est à l'ouest du méridien principal et négatif s'il est à l'est. L'heure doit être comprise entre 0 et 24, et les minutes et secondes 0 et 59. "