Por que o TZ = UTC-8 produz datas que são UTC + 8?

22

A hora atual em Los Angeles é 18:05. Mas quando eu corro TZ=UTC-8 date --iso=ns , fico:

2013-12-07T10:05:37,788173835+0800

O utilitário date me diz que a hora é 10:05 e até diz que está reportando como UTC + 8. Por quê?

    
por Alex Henrie 07.12.2013 / 03:08

4 respostas

30

O motivo é que TZ=UTC-8 é interpretado como um Fuso horário POSIX . No formato de fuso horário POSIX, as 3 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 UTC. Portanto, UTC-8 significa um fuso horário abreviado como "UTC" que é −8 horas atrás do UTC real ou UTC + 8 horas.

(Funciona dessa forma porque o Unix foi desenvolvido nos EUA, que está por trá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 nesses 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 formato do fuso horário ISO -0800 segue a abordagem oposta, com - indicando que a zona está atrás de UTC e + indicando que a zona está à frente do UTC.

    
por 07.12.2013 / 03:45
7

Sempre que você especificar um fuso horário no formato de +/- 00:00, estará especificando um deslocamento , não o fuso horário real. A partir da documentação GNU libc (que segue o padrão POSIX):

The offset specifies the time value you must add to the local time to get a Coordinated Universal Time value. It has syntax like [+|-]hh[:mm[:ss]]. This is positive if the local time zone is west of the Prime Meridian and negative if it is east. The hour must be between 0 and 23, and the minute and seconds between 0 and 59.

É por isso que parece ser o inverso do que você espera.

    
por 07.12.2013 / 03:45
1

Como um método alternativo, você pode usar o comando zdump para mostrar a hora atual em outros fusos horários + offsets.

Zdump prints the current time in each zonename named on the command line.

As mesmas regras se aplicam aos fusos horários; a oeste do meridiano principal está "atrás" enquanto a leste está "à frente".

Exemplo

$ zdump PST PST sab 7 dez 03:25:27 2013 PST

Eu fiz este script para mostrar vários fusos horários + offsets nos quais estamos interessados em usar zdump e date , para que pudéssemos 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 executar, poderá ver a comparação 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)
    
por 07.12.2013 / 03:25
1

Why?

Porque o POSIX exige .

If preceded by a '-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding '+' ).

Então, isso dará tempo próximo a [1] Los Angeles (com qualquer rótulo de 3 letras para texto de 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 um tempo próximo a 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] Perto porque pode haver algum DST (Daylight Saving Time) em vigor que altere a "hora local" real.

    
por 23.04.2016 / 21:03

Tags