
Моя система (Gnome 3 на Debian Testing) путается с текущим временем. Когда я запускаю, date
время отображается правильно, но некоторые приложения отстают на час. Например, когда я добавляю событие в Gnome Calendar, время события, показанное в календаре, будет соответствовать введенному мной времени минус один час.
Я выяснил, в чем проблема, но не знаю, как ее решить:
$ date ; TZ=GMT date ; TZ=BST date
Sun 30 Apr 11:25:37 BST 2017
Sun 30 Apr 10:25:37 GMT 2017
Sun 30 Apr 10:25:37 BST 2017
Первые две строки вывода верны, третья отстает на час. Я не могу понять, почему часовой пояс BST отстает на час, хотя в то же время текущее время верное - и использует BST.
Это также может быть актуально:
$ timedatectl status
Local time: Sun 2017-04-30 11:33:07 BST
Universal time: Sun 2017-04-30 10:33:07 UTC
RTC time: Sun 2017-04-30 10:33:07
Time zone: Europe/London (BST, +0100)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no
Редактировать Вывод zdump /etc/localtime:
$ zdump /etc/localtime
/etc/localtime Sun Apr 30 12:22:53 2017 BST
$ date ; TZ=GMT date ; TZ=BST date
Sun 30 Apr 12:22:53 BST 2017
Sun 30 Apr 11:22:53 GMT 2017
Sun 30 Apr 11:22:53 BST 2017
решение1
BST
не распознается как имя часового пояса. Используется как аббревиатура в выводе, но вы не можете использовать его для обозначения часового пояса. Большинство программ не проверяют имена часовых поясов и молча по умолчанию используют GMT, если имя часового пояса не распознано.
Такие сокращения, как BST, CET, EST и т. д., не всегда четко определены и иногда двусмысленны (это североамериканское или австралийское восточное стандартное время?). Они имеют смысл только в определенном регионе, тогда как конфигурация часового пояса обычно предназначена для использования во всем мире. Более того, сокращение, такое как BST, на самом деле не обозначает часовой пояс, а только время, в котором оно находится в определенном часовом поясе в течение части года (Британия, когда действует летнее время). Поэтому вам следует использовать однозначные обозначения, большинство из которых следуют шаблону континент/город. В типичных системах Linux, и я думаю, во многих других вариантах Unix, вы можете увидеть, какие сокращения доступны, заглянув в каталог /usr/share/zoneinfo
.
Поэтому вместо того, чтобы использовать его GMT
зимой и BST
летом, используйте Europe/London
.
решение2
Как сказал @Gilles, BST — это то, что выводится в date
/ date +%Z
, чтобы сообщить пользователям, что это дата британского летнего времени (то есть GMT+1), а не то, что определяет часовой пояс, и не то, что можно использовать для $TZ
.
Это BST имеет значение для британских пользователей. Когда британский пользователь видит 14:00 BST
, он знает, что временная метка относится к 14:00 летнего времени в материковой части Великобритании (то есть 13:00 UTC). Использование этих 3-4-буквенных кодов широко распространено в Великобритании, США и некоторых других англоговорящих странах, поэтому они отображаются в выводе по умолчанию date
(например, в en_GB.UTF-8
локалях). С другой стороны, большинство французских пользователей не будут иметь ни малейшего представления о том, что 14:00 CEST
означает (хотя CEST
относится кЦентральноевропейское летнее время, часовой пояс GMT+2, который применяется летом во Франции), поэтому вы заметите, что когда даты указывают часовой пояс, они скорее включают смещение UTC, чем CET
/ CEST
там (например mardi 2 mai 2017, 13:34:09 (UTC+0200)
, ).
Переменная $TZ
не должна содержать эти 3-4 буквенные коды. Она содержит что-то, чтоопределяет/указываетчасовой пояс, регион, в котором вы находитесь. Приложения используют его, чтобы узнать смещение относительно UTC в любой момент времени, когда переключаться с зимнего на летнее время и какой код (если таковой имеется) для зимнего и летнего времени будет отображаться пользователю (для тех пользователей, для которых это важно).
Для этого вы можете либо установить TZ
какую-то системную спецификацию часового пояса. Например TZ=:Europe/London
(хотя многие системы также принимают TZ=Europe/London
это), либо TZ
включить полные правила (хотя эти правила ограничены).
Например, если я использую TZ=:Europe/London
в своей системе, то правила будут считываться из /usr/share/zoneinfo/Europe/London
.
В этом файле будет указано, например, что с 1996 года смещение относительно UTC составляет 0 с последнего воскресенья октября в 2 часа ночи по UTC до последнего воскресенья марта (с названием GMT для «среднего времени по Гринвичу») и 1 в противном случае (с названием BST для «британского летнего времени»), тогда как с 1970 года (0 время Unix) по 1972 год оно составляло 1 круглый год с названием BST для «британскогоСтандартВремя".
Вы уже видите, что нет смысла использовать BST в качестве спецификации часового пояса. Во-первых, в разные моменты времени он означал разные вещи, и даже если рассматривать только текущую эпоху, это всего лишь код для летнего времени, поэтому его нельзя использовать в качестве спецификации часового пояса на весь год.
Теперь вы также можете иметь TZ
полные правила. Например, для "British Standard (not Summer) Time" начала 70-х годов вы можете использовать простейшую форму спецификации:
TZ=BST-1
Это определяет часовой пояс, который всегда находится на 1 час к востоку от UTC и для которого date +%Z
всегда возвращается BST
. Этот часовой пояс верен для материковой части Великобритании в начале 70-х годов и для летнего времени с 1972 года, но не для зимнего времени с 1972 года (и мы не можем сказать, что будет в будущем).
Или вы можете использовать полную спецификацию текущих правил:
TZ=GMT0BST,M3.5.0/1:00:00,M10.5.0/2:00:00
Это значит, что в году есть два периода: один называется GMT со смещением 0, а другой — BST со смещением 1 (выше подразумевается как 0+1, если не указано иное), причем переход от одного к другому происходит в последнее (5) воскресенье (0) марта (3) в 1:00:00 UTC и обратно — в последнее воскресенье октября в 2:00.
Опять же, эта TZ работает с 1996 года по настоящее время, но не обязательно в противном случае. Например, для 1970-01-01 00:00:00 UTC (0 время эпохи Unix, когда местное время было 1:00:00 BST (British Standard Time) в Лондоне):
$ TZ=:Europe/London date -d @0
Thu 1 Jan 01:00:00 BST 1970
$ TZ=GMT0BST,M3.5.0/1:00:00,M10.5.0/2:00:00 date -d @0
Thu 1 Jan 00:00:00 GMT 1970
Согласно POSIX, поведение для
TZ=BST-1
хорошо определен (как описано выше)TZ=BST
(илиTZ=GMT
/TZ=UTC
/TZ=Europe/London
) не указано.TZ=:BST
/TZ=:Europe/London
являетсяреализация определенаТо есть системы должны поддерживать это и документировать, что это делает, хотя POSIX не говорит нам, что это делается.
В третьем случае выше, в системах GNU (и, я полагаю, в большинстве других Unix-подобных систем), когда TZ
начинается с :
, то, что следует за ним, берется как путь к файлу определения часового пояса. В случае системы GNU это также случай, когда :
опущен (даже если значение формирует допустимую спецификацию часового пояса, например UTC0
, но, как правило, таких файлов не должно быть, хотя я вижу некоторые исключения в моей системе, которые делают ее не-POSIX-системой (например, TZ=CST6CDT date -d 1943-01-01 +%Z
выводит CWT
вместо , CST
потому что есть /usr/share/zoneinfo/CST6CDT
файл 1 , который определяетвоенное времяна тот период)).
Этот путь обычно является относительным путем, в этом случае он является относительным $TZDIR
(или некоторым значением по умолчанию, например, /usr/share/zoneinfo
когда $TZDIR
не задано, как это обычно бывает). По соображениям безопасности, $TZDIR
абсолютный путь или относительные пути с ..
компонентами игнорируются в контекстах повышения привилегий (например, в контекстах setuid).
Так что обычно в системе GNU, , TZ=:BST
то же самое, как TZ=BST
правило, будет искать /usr/share/zoneinfo/BST
файл. Если не найден (что может быть в случае, если as BST
не может идентифицировать определение часового пояса), он обычно предполагает время UTC и имя часового пояса (как в date +%Z
выводе) BST
.
1 Такие CST6CDT
как WET
, CET
, MET
... являются остатками другого времени. В конце 1993 года база данных TZ (как сейчасподдерживается IANA)измененныйот использования adhoc (и чаще всего неоднозначных) названий (например MET
, , GB-Eire
, WET
) до Area/City
того, где город является самым густонаселенным городом (на момент выпуска), где применяется зона (Площадь — это большие области, такие как континент/океан). Для материковой части Британии, где вы раньше использовали GB-Eire
(не WET), теперь (с 1993 года) вы используете Europe/London
. GB-Eire
(например WET
) по-прежнему доступны для обратной совместимости ( GB-Eire
теперь ссылается на Europe/London
, в то время как WET
определяется как Зона, использующая UTC зимой и Правила ЕС для летнего времени (Британия соблюдает правила ЕС только с 1996 года, и с выходом Великобритании из ЕС никто не может сказать, что ее ждет в будущем)), но не должны использоваться сейчас в новых развертываниях.
решение3
Дополняя ответ Жиля: я нахожусь в том же часовом поясе, что и автор статьи. Западноевропейское время, WET
оно же официальное обозначение; если мне не изменяет память, оно было включено для Португалии в часовые пояса Unix примерно в 1996 году.
https://en.wikipedia.org/wiki/Western_European_Time
Европейское время (WET, UTC±00:00) — часовой пояс, охватывающий части западной и северо-западной Европы.
Следующие страны и регионы используют WET в зимние месяцы:
- Канарские острова, > с 1946 года (остальная часть Испании использует CET, UTC+1) - Фарерские острова, с 1908 года
- Северо-Восточная Гренландия (Данмарксхавн и прилегающие районы)
- Исландия, с 1968 года
- Португалия, с 1912 года с перерывами (кроме Азорских островов, UTC−1)[1]
- Острова Мадейра, с 1912 года с перерывами[2]
- Ирландия, с 1916 года (официально известно как среднее время по Гринвичу), за исключением периода с 1968 по 1971 год
- Соединенное Королевство и зависимые территории Короны, с 1847 года в Англии, Шотландии, Уэльсе, на Нормандских островах и острове Мэн, и с 1916 года в Северной Ирландии (официально известно как среднее время по Гринвичу), с перерывамиВ Соединенном Королевстве с 1940 по 1945 год зимой использовалось британское летнее время (BST=CET), а с 1941 по 1945 год и снова в 1947 году летом использовалось британское двойное летнее время (BDST=CEST). С 18 февраля 1968 года по 31 октября 1971 года BST использовалось круглый год.
Все вышеперечисленные страны, за исключением Исландии, вводят летнее время летом, переходя на западноевропейское летнее время (WEST, UTC+1), которое на один час опережает WET. WEST называется британским летним временем в Великобритании и официально известно как ирландское стандартное время в Ирландии.
В то время как официальное обозначение летнего времени — WEST (западноевропейское летнее время), WET
используется для TZ
и учитывает летнее время/летнее время, сдвигая его на один час вперед.
В наши дни лучшим выбором может быть «Европа/Лондон», однако знание WET
стенографии все еще полезно в некоторых ситуациях.
https://en.wikipedia.org/wiki/Список_часов_зон_базы_данных_tz
Итак, чтобы сравнить результаты с вашим первоначальным тестом:
$date ; TZ=GMT date ; TZ=WET date
Mon May 1 09:36:10 WEST 2017
Mon May 1 08:36:10 GMT 2017
Mon May 1 09:36:10 WEST 2017