La hora actual en Los Ángeles es 18:05. Pero cuando corro TZ=UTC-8 date --iso=ns
, obtengo:
2013-12-07T10:05:37,788173835+0800
La utilidad de fecha me dice que son las 10:05, e incluso dice que lo informa como UTC + 8. ¿Por qué?
La hora actual en Los Ángeles es 18:05. Pero cuando corro TZ=UTC-8 date --iso=ns
, obtengo:
2013-12-07T10:05:37,788173835+0800
La utilidad de fecha me dice que son las 10:05, e incluso dice que lo informa como UTC + 8. ¿Por qué?
Respuestas:
La razón es que TZ=UTC-8
se interpreta como una zona horaria POSIX . En el formato de zona horaria POSIX, las 3 letras son la abreviatura de la zona horaria (que es arbitraria) y el número es la cantidad de horas que la zona horaria está detrás de UTC. Entonces, UTC-8
significa una zona horaria abreviada "UTC" que está −8 horas detrás del UTC real, o UTC + 8 horas.
(Funciona de esa manera porque Unix se desarrolló en los EE. UU., Que está detrás de UTC. Este formato permite que las zonas horarias de EE. UU. Se representen como EST5, CST6, etc.)
Puedes ver que eso es lo que sucede con estos ejemplos:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
El -0800
formato de zona horaria ISO toma el enfoque opuesto, -
indicando que la zona está detrás de UTC e +
indicando que la zona está por delante de UTC.
TZ=America/Los_Angeles
. Olvida que la hora del Pacífico es -7 durante el horario de verano.
TZ=:America/Los_Angeles
. Los dos puntos indican que es un archivo de zona horaria de Olson. Y en otro comentario, mencionó que quería ignorar el horario de verano, lo que no haría.
EST-5
CST-6
.
Cada vez que especifica una zona horaria en el formato de +/- 00:00, está especificando un desplazamiento , no la zona horaria real. De la GNU libc
documentación (que sigue el estándar POSIX):
El desplazamiento especifica el valor de hora que debe agregar a la hora local para obtener un valor de hora universal coordinada. Tiene una sintaxis como [+ | -] hh [: mm [: ss]]. Esto es positivo si la zona horaria local está al oeste del primer meridiano y negativa si está al este. La hora debe estar entre 0 y 23, y los minutos y segundos entre 0 y 59.
Es por eso que parece ser lo contrario de lo que espera.
Why?
Porque POSIX lo requiere .
Si está precedido por un '-', la zona horaria estará al este del meridiano principal; de lo contrario, estará al oeste (lo que puede indicarse mediante un '+' opcional anterior).
Entonces, esto dará tiempo cerca de [1] Los Angeles
(con cualquier etiqueta de 3 letras para el texto de zona horaria):
$ 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
Y esto debería dar el tiempo cerca Shanghai, China
o 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] Cerca porque puede haber algún horario de verano (DST) que cambie la "hora local" real.
Como método alternativo, puede usar el comando zdump
para mostrar la hora actual en otras zonas horarias + compensaciones.
Zdump imprime la hora actual en cada nombre de zona nombrado en la línea de comando.
Las mismas reglas se aplican con las zonas horarias; al oeste del meridiano principal está "atrás" mientras que al este está "adelante".
$ zdump PST PST sáb 7 dic 03:25:27 2013 PST
Hice este script para mostrar varias de las zonas horarias + compensaciones que estamos interesados en usar zdump
y date
para poder compararlas.
$ 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
A continuación, cuando se ejecuta se puede ver la comparación de zdump
a 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
. Gracias. También encontré esta explicación enman timezone
: "La cadena estándar especifica el nombre de la zona horaria y debe tener tres o más caracteres alfabéticos. La cadena de desplazamiento sigue inmediatamente a la norma y especifica el valor de hora que se agregará a la hora local para obtener la hora universal coordinada ( UTC). El desplazamiento es positivo si la zona horaria local está al oeste del Meridiano principal y negativa si está al este. La hora debe estar entre 0 y 24, y los minutos y segundos 0 y 59. "