Aktualny czas w Los Angeles to 18:05. Ale kiedy biegnę TZ=UTC-8 date --iso=ns
, dostaję:
2013-12-07T10:05:37,788173835+0800
Narzędzie daty mówi mi, że jest godzina 10:05, a nawet twierdzi, że zgłasza to jako UTC + 8. Czemu?
Aktualny czas w Los Angeles to 18:05. Ale kiedy biegnę TZ=UTC-8 date --iso=ns
, dostaję:
2013-12-07T10:05:37,788173835+0800
Narzędzie daty mówi mi, że jest godzina 10:05, a nawet twierdzi, że zgłasza to jako UTC + 8. Czemu?
Odpowiedzi:
Powodem jest to, że TZ=UTC-8
jest interpretowana jako strefa czasowa POSIX . W formacie strefy czasowej POSIX trzy litery to skrót strefy czasowej (który jest dowolny), a liczba to liczba godzin, za którymi strefa czasowa znajduje się za czasem UTC. Więc UTC-8
oznacza strefę czasową, w skrócie „UTC”, który jest -8 godziny za realną UTC, czyli UTC + 8 godzin.
(Działa to w ten sposób, ponieważ Unix został opracowany w USA, który stoi za UTC. Ten format umożliwia reprezentowanie stref czasowych w USA jako EST5, CST6 itp.)
Możesz zobaczyć, co dzieje się w tych przykładach:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
-0800
Format strefy czasowej ISO przyjmuje odwrotne podejście, -
wskazując, że strefa znajduje się za UTC, a +
strefa wyprzedza UTC.
TZ=America/Los_Angeles
. Zapominasz, że czas pacyficzny wynosi -7 w czasie letnim.
TZ=:America/Los_Angeles
. Dwukropek wskazuje, że jest to plik strefy czasowej Olsona. W innym komentarzu wspomniał, że chciałby zignorować czas letni, co by tego nie zrobiło.
EST-5
CST-6
.
Ilekroć określisz strefę czasową w formacie +/- 00:00, określasz przesunięcie , a nie rzeczywistą strefę czasową. Z GNU libc
dokumentacji (zgodnej ze standardem POSIX):
Przesunięcie określa wartość czasu, którą należy dodać do czasu lokalnego, aby uzyskać wartość uniwersalnego czasu koordynowanego. Ma składnię taką jak [+ | -] hh [: mm [: ss]]. Jest to pozytywne, jeśli lokalna strefa czasowa znajduje się na zachód od głównego południka, a ujemne, jeśli jest na wschodzie. Godzina musi wynosić od 0 do 23, a minuty i sekundy od 0 do 59.
Dlatego wydaje się, że jest odwrotnością tego, czego oczekujesz.
Why?
Ponieważ POSIX tego wymaga .
Jeśli poprzedza ją „-”, strefa czasowa będzie na wschód od Pierwszego Południka; w przeciwnym razie będzie na zachód (co może być oznaczone opcjonalnym poprzedzającym „+”).
To da czas w pobliżu [1] Los Angeles
(z dowolną trzyliterową etykietą dla tekstu strefy czasowej):
$ 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
To powinno dać czas w pobliżu Shanghai, China
lub 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] Blisko, ponieważ może istnieć jakiś czas letni, który zmienia rzeczywisty „czas lokalny”.
Jako alternatywną metodę możesz użyć polecenia, zdump
aby wyświetlić bieżący czas w innych strefach czasowych + przesunięcia.
Zdump drukuje aktualny czas w każdej nazwie strefy z nazwy w wierszu poleceń.
Te same zasady obowiązują w strefach czasowych; na zachód od głównego południka jest „z tyłu”, a na wschodzie jest „z przodu”.
$ zdump PST PST sob. 7 grudnia 03:25:27 2013 PST
Zrobiłem ten skrypt, aby pokazać kilku stref czasowych + ofsetów jesteśmy zainteresowani w użyciu zdump
, a date
więc możemy je porównać.
$ 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
Wtedy, kiedy go uruchomić można zobaczyć porównanie zdump
do 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
. Dzięki. Znalazłem również to wyjaśnienie wman timezone
: „Ciąg std określa nazwę strefy czasowej i musi składać się z co najmniej trzech znaków alfabetycznych. Ciąg przesunięcia bezpośrednio następuje po std i określa wartość czasu, którą należy dodać do czasu lokalnego, aby uzyskać uniwersalny czas koordynowany ( UTC). Przesunięcie jest dodatnie, jeśli lokalna strefa czasowa znajduje się na zachód od Prime Meridian, i ujemne, jeśli jest na wschód. Godzina musi wynosić od 0 do 24, a minuty i sekundy 0 i 59. ”