Текущее время в Лос-Анджелесе 18:05. Но когда я бегу TZ=UTC-8 date --iso=ns
, я получаю:
2013-12-07T10:05:37,788173835+0800
Утилита date сообщает мне, что время 10:05, и даже говорит, что сообщает об этом как UTC + 8. Зачем?
Текущее время в Лос-Анджелесе 18:05. Но когда я бегу TZ=UTC-8 date --iso=ns
, я получаю:
2013-12-07T10:05:37,788173835+0800
Утилита date сообщает мне, что время 10:05, и даже говорит, что сообщает об этом как UTC + 8. Зачем?
Ответы:
Причина в том, что TZ=UTC-8
интерпретируется как часовой пояс POSIX . В формате часового пояса POSIX 3 буквы обозначают сокращение часового пояса (произвольное), а число - количество часов, в течение которых часовой пояс находится за UTC. Так UTC-8
означает часовой пояс с сокращением UTC, который на 8 часов меньше реального UTC или UTC + 8 часов.
(Это работает так, потому что Unix был разработан в США, который находится за UTC. Этот формат позволяет часовым поясам США быть представленными как EST5, CST6 и т. Д.)
Вы можете увидеть, что происходит на следующих примерах:
$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800
Формат -0800
часового пояса ISO использует противоположный подход, с -
указанием зоны позади UTC и +
указанием зоны впереди UTC.
TZ=America/Los_Angeles
. Вы забываете, что тихоокеанское время составляет -7 в летнее время.
TZ=:America/Los_Angeles
. Двоеточие указывает, что это файл часового пояса Олсона. А в другом комментарии он упомянул, что хочет игнорировать переход на летнее время, чего не будет.
EST-5
CST-6
.
Всякий раз, когда вы указываете часовой пояс в формате +/- 00:00, вы указываете смещение , а не фактический часовой пояс. Из GNU libc
документации (которая соответствует стандарту POSIX):
Смещение указывает значение времени, которое вы должны добавить к местному времени, чтобы получить значение всемирного координированного времени. Он имеет синтаксис вроде [+ | -] чч [: мм [: сс]]. Это положительно, если местный часовой пояс находится к западу от премьер-меридиана, и отрицательно, если он восточнее. Час должен быть от 0 до 23, а минуты и секунды от 0 до 59.
Вот почему это похоже на то, что вы ожидаете.
Why?
Потому что POSIX требует этого .
Если перед ним стоит «-», часовой пояс должен быть восточнее премьер-меридиана; в противном случае он должен быть западным (что может быть указано необязательным предшествующим «+»).
Таким образом, это даст время около [1] Los Angeles
(с любой трехбуквенной меткой для текста часового пояса):
$ 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
И это должно дать время рядом Shanghai, China
или 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] Близко, потому что может существовать некоторое летнее время, которое сдвигает фактическое «местное время».
В качестве альтернативного метода вы можете использовать команду, zdump
чтобы показать текущее время в других часовых поясах + смещения.
Zdump печатает текущее время в каждом названном зонном имени в командной строке.
Те же правила применяются к часовым поясам; к западу от основного меридиана "позади", а к востоку "впереди".
$ zdump PST PST Сб 7 декабря 03:25:27 2013 PST
Я сделал этот скрипт, чтобы показать несколько часовых поясов + смещения, которые нам интересны, zdump
и date
чтобы мы могли их сравнить.
$ 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
Затем, когда вы запустите его, вы можете увидеть сравнение zdump
с 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
. Спасибо. Я также нашел это объяснение в разделеman timezone
: «Строка std указывает имя часового пояса и должна состоять из трех или более буквенных символов. Строка смещения следует сразу же за std и указывает значение времени, которое будет добавлено к местному времени, чтобы получить координированное универсальное время ( UTC). Смещение является положительным, если местный часовой пояс находится к западу от премьер-меридиана, и отрицательным, если оно является восточным. Час должен быть между 0 и 24, а минуты и секунды 0 и 59 ».