L'heure actuelle à Los Angeles est 18:05. Mais quand je cours TZ=UTC-8 date --iso=ns
, j'obtiens:
2013-12-07T10:05:37,788173835+0800
L'utilitaire de date me dit que l'heure est 10:05, et dit même qu'il le rapporte comme UTC + 8. Pourquoi?
La raison en est que TZ=UTC-8
est interprété comme un timezone POSIX . Dans le format de timezone POSIX, les 3 lettres sont l'abréviation du timezone (qui est arbitraire) et le nombre est le nombre d'heures que le timezone est derrière UTC. Donc UTC-8
signifie un timezone abrégé "UTC" qui est -8 heures de retard par rapport à l'UTC réel, ou UTC + 8 heures.
(Cela fonctionne parce qu'Unix a été développé aux États-Unis, ce qui est derrière l'UTC. Ce format permet aux fuseaux horaires américains d'être représentés par EST5, CST6, etc.)
Vous pouvez voir que c'est 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 format de timezone ISO -0800
prend l'approche inverse, avec -
indiquant que la zone est derrière UTC, et +
indiquant que la zone est en avance sur UTC.
Chaque fois que vous spécifiez un timezone au format +/- 00:00, vous spécifiez un décalage et non le timezone réel. De la documentation GNU libc
(qui suit la norme POSIX):
Le décalage spécifie la valeur de time que vous devez append à l'heure locale pour get une valeur de time universel coordonné. Il a la syntaxe comme [+ | -] hh [: mm [: ss]]. Ceci est positif si le timezone local est à l'ouest du premier méridien et négatif s'il est à l'est. L'heure doit être comprise entre 0 et 23 et la minute et la seconde entre 0 et 59.
C'est pourquoi il semble être l'inverse de ce que vous attendez.
Comme méthode alternative, vous pouvez utiliser la command 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 command line.
Les mêmes règles s'appliquent avec les fuseaux horaires; à l'ouest du méridien principal étant «derrière» tandis qu'à l'est «devant».
$ zdump PST PST Sat Dec 7 03:25:27 PST 2013
J'ai fait ce script pour montrer plusieurs des fuseaux horaires + offsets que nous sums intéressés à utiliser zdump
et la date
afin que nous puissions 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
Puis quand 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)
Why?
Parce que POSIX le requirejs .
S'il est précédé d'un «-», le timezone doit être à l'est du méridien principal; sinon, il doit être à l'ouest (ce qui peut être indiqué par un «+» précédant facultatif).
Donc, cela donnera du time près de [1] Los Angeles
(avec n'importe quelle label de 3 lettres pour le timezone du text):
$ 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 time près de 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] Near car il peut y avoir un certain DST (Daylight Saving Time) qui change l'actuelle "heure locale".