Как проверить, какой часовой пояс в Linux?

Вопрос или проблема

Есть ли способ проверить, в каком часовом поясе я нахожусь на Linux?

Обычно переменная окружения TZ даст вам что-то полезное. Однако лучше использовать функции, такие как mktime() и localtime(), для преобразования между time_t и представлением локального часового пояса. То есть, не пытайтесь сделать преобразование самостоятельно.

Если вы имеете в виду из терминала, просто введите:

date +%Z

Если вам нужен числовой часовой пояс:

date +'%:z %Z'

Пример вывода:

-05:00 EST

Я хотел найти часовой пояс в формате “US/Eastern” или “Europe/London”. Вы можете найти это в:

  • /etc/timezone (присутствует на Ubuntu и Red Hat? но не, например, на Amazon Linux)
  • (на системах в стиле Red Hat) как ZONE="US/Eastern" в /etc/sysconfig/clock
  • или вы можете попробовать сопоставить /etc/localtime с одним из файлов под /usr/share/zoneinfo; раздражает, что это, похоже, не символическая ссылка, но вы можете, например,

    cd /usr/share/zoneinfo
    find * -type f -exec sh -c “diff -q /etc/localtime ‘{}’ > /dev/null && echo {}” \;

    чтобы найти соответствующие файлы – вероятно, есть более простые способы сделать это, но это сработает. Будут несколько совпадений.

Иногда вы можете искать канонический часовой пояс, а не сокращенный вариант, как выдает date %Z, например, US/Eastern. На системах с timedatectl, например, Fedora, timedatectl выводит множество полезной информации, включая текущую зону:

# timedatectl
      Местное время: Вт 2016-09-13 17:10:26 EDT
  Всемирное время: Вт 2016-09-13 21:10:26 UTC
        Время RTC: Вт 2016-09-13 21:10:26
       Часовой пояс: US/Eastern (EDT, -0400)
 Время сети включено: да
Синхронизировано по NTP: да
 RTC в локальном TZ: нет

К сожалению, timedatectl принимает set-timezone как команду, но не имеет соответствующей get-timezone. Разберите его следующим образом:

# timedatectl status | grep "zone" | sed -e 's/^[ ]*Time zone: \(.*\) (.*)$/\1/g'`
US/Eastern

Для systemd >= 241, смотрите @Ответ BurninateSE (TLDR: timedatectl show --va -p Timezone).

Для ubuntu попробуйте следующее:

$ cat /etc/timezone

Пример вывода:

Asia/Kolkata

Для других дистрибутивов ссылка: https://unix.stackexchange.com/questions/110522/timezone-setting-in-linux

Для определения часового пояса вы можете использовать геолокацию:

$ curl https://ipapi.co/timezone
America/Chicago

Или:

$ curl http://ip-api.com/line?fields=timezone
America/Chicago

http://wiki.archlinux.org/index.php/time#Time_zone

Все приведенные ниже решения дадут вам IANA совместимый идентификатор часового пояса Olson (например, America/Los_Angeles). Тем не менее, некоторые из них могут возвращать лишние пробелы в начале и/или в конце – удалите их, если это необходимо.

Используя переменные окружения

Переменная окружения TZ (если установлена) определяет часовой пояс. Проверка этого в первую очередь необходима.

$ echo $TZ

Я могу лично подтвердить, что это работает на ВСЕХ моих современных Linux-хостах.

Используя Systemd версии >= 241

Это предпочтительный метод для всех, кто считает, что Systemd должен править миром.

$ timedatectl show --va -p Timezone

Если вы получите ошибку, подобную timedatectl: недопустимый параметр -- 'p', это означает, что ваш Systemd не готов править миром. Вместо этого…

Используя Systemd и sed

Улучшение ответа Рамана, но без бесполезного использования grep. Это решение оптимально на системах с более старыми версиями Systemd.

$ timedatectl | sed -n 's/^\s*Time zone: \(.*\) (.*/\1/p'

Используя /etc/timezone

Это простой читаемый файл, но, похоже, он больше не доступен на большом количестве дистрибутивов. Если я правильно помню, это то, что разработчики Debian придумали некоторое время назад, но это вышло из моды.

$ cat /etc/timezone

Используя GNU realpath поскольку /etc/localtime является символической ссылкой

Это решение оптимально, если вы знаете, что /etc/localtime является символической ссылкой, что делают как старые программные решения, так и современные руководства; и у вас также есть GNU realpath, который должен быть доступен на каждом дистрибутиве GNU OS.

$ realpath --relative-to /usr/share/zoneinfo /etc/localtime

Ой! /etc/localtime не является символической ссылкой; используя find, sed, md5sum

Если вы обнаружите, что /etc/localtime не является символической ссылкой (команда, показанная выше, либо выдаст ошибку, либо предоставит путь, начинающийся с ../), вы можете попробовать найти его md5-совпадение в вашей локальной базе данных часовых поясов. Это может вернуть несколько совпадений, так как в базе данных Olson есть множество псевдонимов.

$ find /usr/share/zoneinfo -type f -exec md5sum {} + |\
  sed /$(printf $(md5sum /etc/localtime))/'!d;s/.\{54\}//;/^posix/d'

Если вы хотите получить только один идентификатор часового пояса (любой, который вернет система readdir()), вы можете использовать команду q в sed, чтобы выйти после первого совпадения. Это намного эффективнее, чем запускать head, например. Однако это вызывает сбой find на пайпе с md5sum раньше, что приводит к выводу ошибки на fd 2. Вы можете игнорировать эту ошибку, передав ее в /dev/null, как показывает следующая полная команда:

$ find /usr/share/zoneinfo -type f -exec md5sum {} + 2> /dev/null |\
  sed /$(printf $(md5sum /etc/localtime))/'!d;s/.\{54\}//;/^posix/d;q'

Используя curl и геолокацию

Если по какой-то причине вы не хотите или не доверяете конфигурации хоста (или просто не любите его), но вы уверены, что он может подключаться к более широкому интернету, существует несколько бесплатных онлайн-сервисов, которые могут вас геолокализировать (пока они еще работают). Ниже приведены некоторые примеры:

$ curl -Lsf https://ipapi.co/timezone # Неактивный?

$ curl -Lsf http://ip-api.com/line?fields=timezone

$ curl -Lsf https://ipwhois.app/line/?objects=timezone

$ curl -Lsf http://api.ipgeolocation.io/timezone -e ';auto' | jq -r .timezone

Первые два сервиса без стыда украдены из ответа Стивена Пенни. Кроме того, я призываю сообщество SE поддерживать этот список актуальным с работающими ссылками, спасибо!

Также обратите внимание, что хотя эти сервисы бесплатны, пожалуйста, посетите их соответствующие веб-сайты, чтобы узнать о и принять их условия перед использованием.

PS наконец, пожалуйста, не используйте этот метод, чтобы связывать своих пользователей и красть их возможности – используйте этот метод только если они просят вас сделать это!

$ strings /etc/localtime | tail -n 1
MST7MDT,M3.2.0,M11.1.0

Итак, я в горном времени.
Хотя приведенные выше советы по использованию переменной окружения или просто выводу команды date иногда работают лучше, в зависимости от того, как вы хотите это использовать.

У меня Linux Mint Cinnamon.
timedatectl дал мне нужную информацию:

                  Местное время: Пн 2020-06-29 11:04:27 PDT
              Всемирное время: Пн 2020-06-29 18:04:27 UTC
                    Время RTC: Пн 2020-06-29 18:04:27
                   Часовой пояс: America/Vancouver (PDT, -0700)
   Системные часы синхронизированы: да

Активна служба systemd-timesyncd.service: да
RTC в локальном TZ: нет

  • /etc/sysconfig/clock устанавливает, сохраняется ли аппаратное время как UTC или местное время.
  • Символическая ссылка /etc/localtime на /usr/share/zoneinfo/… для установки вашего часового пояса.
  • Введите /sbin/hwclock --systohc [--utc], чтобы установить аппаратные часы.

Ядро Linux всегда хранит и вычисляет время как количество секунд с полуночи 1 января 1970 года UTC, независимо от того, хранится ли ваше аппаратное время как UTC или нет. Преобразования в ваше местное время выполняются во время выполнения. Одна интересная вещь в этом заключается в том, что если кто-то использует ваш компьютер из другого часового пояса, он может установить переменную окружения TZ, и все даты и времена будут отображаться правильно для их часового пояса.

Если количество секунд с 1 января 1970 года UTC хранится как знаковое 32-разрядное целое (как это происходит в вашей системе Linux/Intel), ваши часы перестанут работать в какой-то момент в 2038 году. У Linux нет проблем Y2K, но он имеет проблему года 2038. Надеюсь, к тому времени мы все будем использовать Linux на 64-разрядных системах. 64-разрядные целые числа будут поддерживать наши часы довольно хорошо до примерно 292271 миллионов.

Использование TZ или date НЕ ЯВЛЯЕТСЯ НАДЕЖНЫМ, поскольку они сообщают вам часовой пояс ПОЛЬЗОВАТЕЛЯ, а не часовой пояс системы по умолчанию.

Часовой пояс системы по умолчанию хранится в /etc/timezone (который часто является символической ссылкой на файл данных часового пояса, специфичный для часового пояса). Если у вас нет /etc/timezone, посмотрите в /etc/localtime. Обычно это “серверный” часовой пояс. /etc/localtime часто является символической ссылкой на файл часового пояса в /usr/share/zoneinfo. Этот путь к правильному файловому часовому поясу также часто подсказывает географическую информацию.

Новые версии Linux имеют “timedatectl”, который дает множество информации при выполнении команды.

(в качестве примечания, если у вас есть древняя система, которая все еще использует СТАРЫЕ жестко закодированные часовые пояса, вы, вероятно, можете скопировать современный файл часового пояса на нее, и это будет работать. Мне приходилось делать это много раз, чтобы разрешить изменения часовых поясов на старом оборудовании).

Парочка решений:

date +"%Z %z"
timedatectl | grep "Time zone"
cat /etc/timezone

дали мне (соответственно):

UTC +0000
Часовой пояс: Etc/UTC (UTC, +0000)
Etc/UTC

Мой компьютер находится на UTC.

Systemd добавил больше опций, так что я не должен много использовать grep, sed или awk:

$ timedatectl show -p Timezone --value
Europe/Berlin

Это работает на Debian Buster (systemd 241), но не на Ubuntu 18.04 Bionic (systemd 237). Поэтому я теперь использую это в скриптах, чтобы сохранить это простым и чистым:

$ timedatectl show -p Timezone --value || cat "/etc/timezone"
Europe/Berlin

Иногда timedatectl set-timezone не обновляет /etc/timezone, поэтому лучше получить часовой пояс из имени файла, на который указывает символическая ссылка /etc/timezone:

#!/bin/bash
set -euo pipefail

if filename=$(readlink /etc/localtime); then
    # /etc/localtime является символической ссылкой, как ожидалось
    timezone=${filename#*zoneinfo/}
    if [[ $timezone = "$filename" || ! $timezone =~ ^[^/]+/[^/]+$ ]]; then
        # не указывает на ожидаемое местоположение или не Регион/Город
        >&2 echo "$filename указывает на неожиданное местоположение"
        exit 1
    fi
    echo "$timezone"
else  # сравните файлы по содержимому
    # https://stackoverflow.com/questions/12521114/getting-the-canonical-time-zone-name-in-shell-script#comment88637393_12523283
    find /usr/share/zoneinfo -type f ! -regex ".*/Etc/.*" -exec \
        cmp -s {} /etc/localtime \; -print | sed -e 's@.*/zoneinfo/@@' | head -n1
fi

Ссылки: в этом ответе.

Вы можете показать дату и часовой пояс одновременно:

date +'%d/%m/%Y  %H:%M:%S [%:z  %Z]'

.

Ответ или решение

Чтобы проверить, в каком часовом поясе вы находитесь в операционной системе Linux, можно воспользоваться несколькими простыми и эффективными методами. Ниже мы подробно рассмотрим эти методы, их преимущества и особенности.

1. Использование переменной окружения TZ

Первый способ — это проверить переменную окружения TZ, которая может сообщить о текущем часовом поясе. Выполните следующую команду в терминале:

echo $TZ

Если переменная установлена, она отобразит используемый часовой пояс. Однако, имейте в виду, что этот способ может быть ненадежен, так как он отображает только пользовательский часовой пояс.

2. Команда date

Команда date — один из самых простых способов узнать текущий часовой пояс. Для этого выполните команду:

date +%Z

Для получения числового значения часового пояса выполните:

date +'%:z %Z'

Пример вывода:

-05:00 EST

3. Использование timedatectl

Если ваша система использует systemd, вы можете воспользоваться командой timedatectl, которая предоставляет актуальную информацию о времени и часовом поясе. Для получения подробной информации выполните:

timedatectl

Вывод будет содержать такие сведения, как локальное время, универсальное время и часовой пояс. Чтобы получить только значение часового пояса, используйте следующую команду:

timedatectl show -p Timezone --value

Для систем с более старыми версиями systemd, где указанная команда может не поддерживаться, можно использовать альтернативный метод:

timedatectl | grep "Time zone"

4. Проверка файла /etc/timezone

На системах, таких как Ubuntu, вы можете обратиться к файлу /etc/timezone, где обычно хранится информация о часовом поясе:

cat /etc/timezone

5. Сравнение файла /etc/localtime

Файл /etc/localtime обычно является символьной ссылкой на файл в директории /usr/share/zoneinfo, который соответствует вашему текущему часовому поясу. В случае если localtime не является симлинком, можно выполнить команду:

find /usr/share/zoneinfo -type f -exec md5sum {} + | \
sed /$(printf $(md5sum /etc/localtime))/'!d;s/.\{54\}//;/^posix/d'

6. Использование геолокации

Если вы хотите узнать часовой пояс без обращения к конфигурациям системы, можно воспользоваться сервисами геолокации. Например:

curl https://ipapi.co/timezone

или

curl http://ip-api.com/line?fields=timezone

Заключение

Каждый из вышеперечисленных методов предоставляет актуальную информацию о текущем часовом поясе в Linux. Команда timedatectl является самой полной и предпочтительной, предоставляя широкий спектр информации, включая поддержку и автоматическое обновление. Используйте метод, который наилучшим образом соответствует вашим нуждам и особенностям вашей системы.

Не забывайте, что правильная настройка часового пояса важна для многих приложений и можно избежать потенциальных проблем с временем, особенно в распределённых системах.

Оцените материал
Добавить комментарий

Капча загружается...