Поточний час у Лос-Анджелесі о 18:05. Але коли я біжу TZ=UTC-8 date --iso=ns
, я отримую:
2013-12-07T10:05:37,788173835+0800
Утиліта дати повідомляє мені, що час 10:05, і навіть каже, що вона повідомляє про це як UTC + 8. Чому?
Поточний час у Лос-Анджелесі о 18:05. Але коли я біжу TZ=UTC-8 date --iso=ns
, я отримую:
2013-12-07T10:05:37,788173835+0800
Утиліта дати повідомляє мені, що час 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):
Зсув визначає значення часу, яке потрібно додати до місцевого часу, щоб отримати координоване загальне значення часу. Він має синтаксис, як [+ | -] hh [: mm [: ss]]. Це позитивно, якщо місцевий часовий пояс знаходиться на захід від головного меридіана і негативний, якщо він східний. Година повинна становити між 0 і 23, а хвилина і секунди між 0 і 59.
Ось чому це, здається, є зворотним для того, що ви очікуєте.
Why?
Тому що POSIX цього вимагає .
Якщо передує "-", часовий пояс знаходиться на схід від основного меридіана; в іншому випадку це захід (що може бути позначено необов'язковим попереднім "+").
Отже, це дасть час поблизу [1] Los Angeles
(з будь-якою 3-літерною міткою для тексту часового поясу):
$ 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] Поруч, оскільки може бути деякий DST (літній час), який змінює фактичний "місцевий час".
Як альтернативний метод, ви можете використовувати команду 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 ".