Perché TZ = UTC-8 produce date UTC + 8?


25

L'ora corrente a Los Angeles è 18:05. Ma quando corro TZ=UTC-8 date --iso=ns, ottengo:

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

L'utilità di data mi dice che l'ora è 10:05 e persino dice che lo sta segnalando come UTC + 8. Perché?

Risposte:


33

Il motivo è che TZ=UTC-8viene interpretato come un fuso orario POSIX . Nel formato di fuso orario POSIX, le 3 lettere sono l'abbreviazione del fuso orario (che è arbitraria) e il numero è il numero di ore in cui il fuso orario è dietro UTC. Quindi UTC-8significa un fuso orario "UTC" abbreviato che è −8 ore dietro il UTC reale o UTC + 8 ore.

(Funziona in questo modo perché Unix è stato sviluppato negli Stati Uniti, che è dietro UTC. Questo formato consente di rappresentare i fusi orari statunitensi come EST5, CST6, ecc.)

Puoi vedere che è quello che sta succedendo da questi esempi:

$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800

Il -0800formato ISO del fuso orario ha l'approccio opposto, con l' -indicazione che la zona è dietro UTC e che +indica che la zona è avanti rispetto a UTC.


Ah, quindi quello che volevo davvero era TZ=PST+8 date. Grazie. Ho anche trovato questa spiegazione sotto man timezone: "La stringa std specifica il nome del fuso orario e deve contenere tre o più caratteri alfabetici. La stringa offset segue immediatamente std e specifica il valore temporale da aggiungere all'ora locale per ottenere l'ora coordinata universale ( UTC). L'offset è positivo se il fuso orario locale è a ovest del meridiano principale e negativo se è a est. L'ora deve essere compresa tra 0 e 24 e i minuti e secondi 0 e 59. "
Alex Henrie,

3
@Alex no, quello che vuoi davvero è TZ=America/Los_Angeles. Si sta dimenticando che l'ora del Pacifico è -7 durante l'ora legale.
Matt Johnson-Pint il

3
@MattJohnson, intendi TZ=:America/Los_Angeles. I due punti indicano che si tratta di un file fuso orario Olson. E in un altro commento, ha menzionato che voleva ignorare l'ora legale, cosa che non avrebbe fatto.
cjm

@cjm, grazie, hai ragione sul colon e non avevo visto quel commento.
Matt Johnson-Pint,

America, causa del mondo se significa che dobbiamo essere EST-5 CST-6.
Evan Carroll,

7

Ogni volta che specifichi un fuso orario nel formato di +/- 00:00, stai specificando un offset , non il fuso orario effettivo. Dalla GNU libc documentazione (che segue lo standard POSIX):

L'offset specifica il valore temporale che è necessario aggiungere all'ora locale per ottenere un valore di tempo universale coordinato. Ha una sintassi come [+ | -] hh [: mm [: ss]]. Ciò è positivo se il fuso orario locale è ad ovest del meridiano principale e negativo se è ad est. L'ora deve essere compresa tra 0 e 23 e il minuto e i secondi tra 0 e 59.

Questo è il motivo per cui sembra essere il contrario di ciò che ti aspetti.


2

Why?

Perché POSIX lo richiede .

Se preceduto da un '-', il fuso orario deve essere ad est del Meridiano Primo; in caso contrario, deve essere ad ovest (che può essere indicato da un precedente "+" facoltativo).

Quindi, questo darà il tempo vicino a [1] Los Angeles (con un'etichetta di 3 lettere per il testo del fuso orario):

$ 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 questo dovrebbe dare il tempo vicino Shanghai, Chinao 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] Vicino perché potrebbe esserci qualche ora legale (DST) che sposta effettivamente l '"ora locale" effettiva.


1

Come metodo alternativo puoi usare il comando zdump per mostrare l'ora corrente in altri fusi orari + offset.

Zdump stampa l'ora corrente in ogni zonename indicato sulla riga di comando.

Le stesse regole si applicano con i fusi orari; a ovest del meridiano principale è "dietro" mentre a est è "avanti".

Esempio

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

Ho realizzato questo script per mostrare diversi fusi orari + offset che siamo interessati a utilizzare zdumpe in datemodo da poterli confrontare.

$ 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

Poi, quando si esegue esso si può vedere il confronto di zdumpa 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)

In realtà sto cercando di ottenere l'ora corrente nell'ora solare del Pacifico, ignorando l'ora legale.
Alex Henrie,

1
Ho dovuto sottovalutare questo perché stai indovinando che "UTC-8" non è corretto. È corretto, semplicemente non fa ciò che l'utente si aspetta. Non credo che risponda alla domanda sul perché funzioni in questo modo.
Giordania,

@jordanm - guarda la pulizia.
slm

1
Spiega ancora cosa sta succedendo ma non perché e "perché" è ciò che OP sta chiedendo. Rimuoverò il mio voto negativo ma ancora non mi sento come se fosse una buona risposta alla domanda.
Giordania,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.