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é?
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:
Il motivo è che TZ=UTC-8
viene 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-8
significa 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 -0800
formato 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.
TZ=America/Los_Angeles
. Si sta dimenticando che l'ora del Pacifico è -7 durante l'ora legale.
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.
EST-5
CST-6
.
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.
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, 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] Vicino perché potrebbe esserci qualche ora legale (DST) che sposta effettivamente l '"ora locale" effettiva.
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".
$ 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 zdump
e in date
modo 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 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
. Grazie. Ho anche trovato questa spiegazione sottoman 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. "