O horário atual em Los Angeles é 18:05. Mas quando corro TZ=UTC-8 date --iso=ns
, recebo:
2013-12-07T10:05:37,788173835+0800
O utilitário date me diz que a hora é 10:05 e até diz que está relatando como UTC + 8. Por quê?
O horário atual em Los Angeles é 18:05. Mas quando corro TZ=UTC-8 date --iso=ns
, recebo:
2013-12-07T10:05:37,788173835+0800
O utilitário date me diz que a hora é 10:05 e até diz que está relatando como UTC + 8. Por quê?
Respostas:
O motivo é que TZ=UTC-8
é interpretado como um fuso horário POSIX . No formato do fuso horário POSIX, as três letras são a abreviação do fuso horário (que é arbitrária) e o número é o número de horas que o fuso horário está atrás do UTC. Portanto, UTC-8
significa um fuso horário abreviado "UTC" que é de -8 horas atrás do UTC real, ou UTC + 8 horas.
(Funciona assim porque o Unix foi desenvolvido nos EUA, atrás do UTC. Esse formato permite que os fusos horários dos EUA sejam representados como EST5, CST6 etc.)
Você pode ver o que está acontecendo com estes exemplos:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
O -0800
formato do fuso horário ISO adota a abordagem oposta, -
indicando que a zona está atrás do UTC e +
indicando que a zona está à frente do UTC.
TZ=America/Los_Angeles
. Você está esquecendo que o horário do Pacífico é -7 durante o horário de verão.
TZ=:America/Los_Angeles
. Os dois pontos indicam que é um arquivo de fuso horário da Olson. E em outro comentário, ele mencionou que queria ignorar o horário de verão, o que não faria.
EST-5
CST-6
.
Sempre que você especifica um fuso horário no formato de +/- 00:00, está especificando um deslocamento , não o fuso horário real. A partir da GNU libc
documentação (que segue o padrão POSIX):
O deslocamento especifica o valor da hora que você deve adicionar à hora local para obter um valor de Tempo Universal Coordenado. Possui sintaxe como [+ | -] hh [: mm [: ss]]. Isso é positivo se o fuso horário local estiver a oeste do Meridiano Prime e negativo se estiver a leste. A hora deve estar entre 0 e 23 e os minutos e segundos entre 0 e 59.
É por isso que parece ser o inverso do que você espera.
Why?
Porque o POSIX exige .
Se precedido por um '-', o fuso horário deve estar a leste do Primeiro Meridiano; caso contrário, deve ser oeste (o que pode ser indicado por um '+' precedente opcional).
Portanto, isso dará um tempo próximo a [1] Los Angeles
(com qualquer rótulo de três letras para o texto do fuso horário):
$ 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
E isso deve dar o tempo próximo 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] Próximo, pois pode haver algum horário de verão que altera a "hora local" real.
Como método alternativo, você pode usar o comando zdump
para mostrar a hora atual em outros fusos horários + compensações.
O Zdump imprime a hora atual em cada nome de zona nomeado na linha de comando.
As mesmas regras se aplicam aos fusos horários; oeste do meridiano principal estar "atrás", enquanto o leste estar "à frente".
$ zdump PST PST Sáb 7 de dezembro 03:25:27 2013 PST
Eu criei esse script para mostrar vários dos fusos horários + desvios que estamos interessados em usar zdump
e date
para podermos compará-los.
$ 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
Então, quando você o executa, pode ver a comparação de zdump
para 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
. Obrigado. Também encontrei esta explicação emman timezone
: "A string std especifica o nome do fuso horário e deve ter três ou mais caracteres alfabéticos. A string de deslocamento segue imediatamente std e especifica o valor da hora a ser adicionado à hora local para obter o Tempo Universal Coordenado ( UTC). O deslocamento é positivo se o fuso horário local estiver a oeste do Meridiano Prime e negativo se estiver a leste. A hora deve estar entre 0 e 24 e os minutos e segundos 0 e 59. "