Главная / База знаний / Часовой пояс и локаль на Linux-сервере: настройка и типичные ошибки
инструкция · 6 ноября 2026

Часовой пояс и локаль на Linux-сервере: настройка и типичные ошибки

Как правильно настроить часовой пояс и локаль на VPS: почему UTC — разумный дефолт для серверов, как работают timedatectl и locale-gen, и какие баги возникают из-за рассинхронизации времени и локали.

Почему часовой пояс сервера — это не мелочь

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

Часовой пояс определяет, какое локальное время показывается пользователю (администратору, читающему логи, или коду приложения, вызывающему функции текущего времени), тогда как внутреннее системное время Linux всегда хранится в виде количества секунд, прошедших с начала эпохи Unix, в UTC — часовой пояс применяется только на этапе отображения этого значения человеку или приложению. Отсюда следует важный практический вывод: сама смена часового пояса не меняет физическое время на сервере, она лишь меняет то, как это время интерпретируется и показывается.

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

Эта статья разбирает практическую настройку обоих параметров через timedatectl и locale-gen, объясняет, почему UTC — разумный выбор часового пояса именно для серверной инфраструктуры, и разбирает конкретные баги, которые чаще всего возникают из-за рассинхронизации часового пояса или локали между разными частями системы.

UTC как разумный дефолт для серверов

Универсальное согласованное время (UTC) не подвержено переходу на летнее и зимнее время и не меняется по политическим решениям отдельных стран об изменении границ часовых поясов — в отличие от местных часовых поясов вроде Europe/Moscow или America/New_York, которые в разные годы истории неоднократно меняли своё смещение относительно UTC из-за законодательных решений. Для сервера, который должен работать стабильно и предсказуемо годами, это уже весомый довод в пользу UTC как базовой настройки.

Более практичная причина — при работе с несколькими серверами (веб-сервер, база данных, сервер очередей, реплики в другом дата-центре) сопоставление меток времени из логов разных машин требует, чтобы все они использовали одну и ту же систему отсчёта; если один сервер стоит в Europe/Moscow, а другой в UTC, администратору придётся вручную вычислять разницу в три часа при каждом сопоставлении событий, а во время инцидента под давлением времени такие ручные пересчёты — источник реальных ошибок.

Вывод timedatectl на сервере с корректно настроенным UTC и работающей синхронизацией времени
timedatectl
                Local time: чт 2026-11-06 07:00:00 UTC
            Universal time: чт 2026-11-06 07:00:00 UTC
                  RTC time: чт 2026-11-06 07:00:00
                 Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active

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

timedatectl: просмотр и смена часового пояса

В современных дистрибутивах на базе systemd (Ubuntu, Debian, CentOS/AlmaLinux, Rocky Linux) управление часовым поясом и синхронизацией времени выполняется утилитой timedatectl, входящей в состав systemd — она заменяет собой более старые и разрозненные инструменты вроде dpkg-reconfigure tzdata.

Просмотр доступных часовых поясов по маске и установка нужного
timedatectl list-timezones | grep Moscow
timedatectl set-timezone Europe/Moscow
timedatectl set-timezone UTC

Команда timedatectl list-timezones выводит полный список поддерживаемых имён часовых поясов базы данных IANA tz — именно эти имена (Europe/Moscow, Asia/Novosibirsk, UTC) используются во всех современных инструментах, поскольку они однозначно учитывают историю переходов на летнее время и изменений смещения для конкретного региона, в отличие от простых сокращений вроде MSK, которые не всегда однозначны и не учитывают исторические изменения.

Команда timedatectl set-timezone применяет изменение немедленно, без перезагрузки сервера, и сразу отражается в выводе date и в новых записях системного журнала. Важная деталь: уже запущенные процессы, которые прочитали часовой пояс на старте и сохранили его во внутреннем состоянии (это не самый частый случай, но встречается у некоторых демонов и у приложений с длительным временем жизни процесса), могут не подхватить изменение до собственного перезапуска — если после смены часового пояса какой-то сервис продолжает вести себя по-старому, стоит проверить именно эту возможность.

/etc/timezone, /etc/localtime и что их связывает

Под капотом timedatectl set-timezone изменяет символическую ссылку /etc/localtime, указывающую на конкретный файл описания часового пояса в каталоге /usr/share/zoneinfo, и параллельно обновляет текстовый файл /etc/timezone (в дистрибутивах на базе Debian и Ubuntu) с человекочитаемым именем текущего часового пояса.

Символическая ссылка на файл конкретного часового пояса и дублирующий текстовый файл
ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 ноя  6 07:00 /etc/localtime -> /usr/share/zoneinfo/Europe/Moscow

cat /etc/timezone
Europe/Moscow

Некоторые унаследованные скрипты и старые версии приложений читают часовой пояс напрямую из /etc/timezone вместо того, чтобы вызывать системные функции работы со временем, поэтому при ручном редактировании конфигурации (что в целом не рекомендуется — лучше пользоваться timedatectl) важно синхронизировать оба файла, иначе разные части системы могут увидеть разный часовой пояс до следующей перезагрузки или явной перепроверки.

Отдельный случай — контейнеры Docker: часовой пояс внутри контейнера по умолчанию не наследуется от хост-системы и обычно равен UTC, если явно не смонтировать /etc/localtime и /etc/timezone с хоста или не установить переменную окружения TZ внутри самого контейнера. Приложения, разворачиваемые в контейнерах и рассчитывающие на конкретный местный часовой пояс, должны либо получать его явно через переменную TZ, либо форматировать все даты, ориентируясь на UTC и переводя их в нужный часовой пояс уже на уровне бизнес-логики.

Локаль: что это и зачем она серверу

Локаль (locale) в Unix-подобных системах определяет набор региональных соглашений: язык системных сообщений, формат вывода чисел и денежных сумм (разделитель тысяч, десятичный разделитель), формат даты и времени при выводе через системные утилиты, а также порядок сортировки строк с учётом алфавита конкретного языка. Имя локали формируется по шаблону язык_СТРАНА.КОДИРОВКА, например ru_RU.UTF-8 или en_US.UTF-8.

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

Вывод всех текущих переменных локали для активной оболочки
locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_ALL=

Отсутствие нужной локали в системе (а не только неправильно выбранная) — распространённая проблема на минимальных установках серверных образов, где по умолчанию сгенерирована лишь одна базовая локаль вроде C.UTF-8 или en_US.UTF-8, а нужная региональная локаль ещё даже не сгенерирована и её нужно добавить явно перед использованием.

locale-gen и update-locale: генерация и выбор локали

Прежде чем локаль можно использовать, её нужно сгенерировать — в дистрибутивах на базе Debian и Ubuntu список локалей, доступных для генерации, находится в файле /etc/locale.gen, где нужные строки нужно раскомментировать перед запуском генератора.

Раскомментирование нужной локали, генерация и установка системной локалью по умолчанию
sudo sed -i 's/^# *\(ru_RU.UTF-8 UTF-8\)/\1/' /etc/locale.gen
sudo locale-gen
sudo update-locale LANG=ru_RU.UTF-8 LC_TIME=ru_RU.UTF-8

Команда locale-gen компилирует раскомментированные в /etc/locale.gen локали в бинарный формат, который затем используют системные библиотеки, а update-locale записывает значения по умолчанию для переменных LANG и, при необходимости, отдельных LC_* в файл /etc/default/locale, применяемый при каждом новом входе в систему. Изменение вступает в силу для новых сессий и новых процессов; уже открытые оболочки и запущенные сервисы продолжают работать со старой локалью, унаследованной при их запуске, до перелогина или перезапуска.

В дистрибутивах на базе RHEL (CentOS, AlmaLinux, Rocky Linux) механизм отличается: список установленных локалей смотрят командой localectl list-locales, а установка выполняется через localectl set-locale LANG=ru_RU.UTF-8 — сам подход к разделению на генерацию и выбор активной локали в целом схож с Debian-семейством, но имена команд и расположение конфигурационных файлов различаются, и это стоит учитывать при переносе инструкций между разными дистрибутивами.

Переменные LC_* и их практическое значение

Локаль на самом деле — не одна настройка, а целая группа независимых переменных окружения с префиксом LC_, каждая из которых отвечает за собственный аспект: LC_TIME — формат даты и времени, LC_NUMERIC — формат чисел, LC_MONETARY — формат денежных сумм, LC_COLLATE — порядок сортировки строк, LC_MESSAGES — язык системных сообщений программ, поддерживающих локализацию через gettext.

Переменная LANG задаёт значение по умолчанию сразу для всех LC_*, если конкретная из них не переопределена явно, а переменная LC_ALL, если она установлена, принудительно перекрывает вообще все остальные настройки локали, включая LANG и любые отдельно заданные LC_*, — это удобно для временного переключения локали в рамках одной команды или скрипта, но опасно оставлять LC_ALL установленной постоянно, поскольку она незаметно перекрывает более гибкую и явную настройку через отдельные LC_* переменные.

Разница в порядке сортировки одного и того же файла в зависимости от локали сортировки
LC_ALL=C sort file.txt
LC_COLLATE=ru_RU.UTF-8 sort file.txt

Практический пример, где несовпадение LC_COLLATE реально заметно: сортировка строк с кириллицей через утилиту sort в локали C (или POSIX) выполняется побайтово по числовым кодам символов, что для кириллицы в UTF-8 даёт порядок, ощутимо отличающийся от привычного алфавитного, тогда как локаль ru_RU.UTF-8 сортирует строки по правилам русского алфавита. Скрипты обработки текста, полагающиеся на алфавитный порядок сортировки, должны либо явно задавать нужную LC_COLLATE, либо не полагаться на локаль сервера по умолчанию, если она может отличаться между разными окружениями (разработка, staging, production).

Типичная проблема: cron выполняется не в то время

Один из самых частых практических симптомов рассинхронизации часового пояса — задачи cron, срабатывающие со сдвигом относительно ожидания администратора. Классический сценарий: сервер изначально был поднят с часовым поясом UTC, администратор прописал задачу на 03:00 по местному времени, ориентируясь на привычные часы своего региона, но забыл, что crontab интерпретирует время в системном часовом поясе, а не в том, что подразумевал человек при написании расписания.

Задача cron, время выполнения которой не совпало с ожиданием из-за системного часового пояса UTC
# crontab -e — предполагалось "03:00 ночи по Москве"
0 3 * * * /usr/local/bin/nightly-backup.sh
# в реальности выполнится в 03:00 UTC = 06:00 по Москве (UTC+3)

Решить эту проблему можно двумя способами: либо явно перевести сервер на нужный местный часовой пояс через timedatectl set-timezone, если весь сервер логически привязан к одному региону, либо, если менять системный часовой пояс нежелательно (например, сервер обслуживает несколько регионов или намеренно держится на UTC по описанным выше причинам), указать часовой пояс прямо в самом crontab через переменную CRON_TZ (поддерживается современным cronie и Vixie cron) или TZ, применимую к конкретной задаче или ко всему файлу.

Явное указание часового пояса для конкретного crontab независимо от системного часового пояса сервера
CRON_TZ=Europe/Moscow
0 3 * * * /usr/local/bin/nightly-backup.sh

Похожая проблема встречается и с systemd timers — юнит-файлы таймеров по умолчанию тоже интерпретируют время в системном часовом поясе, и если требуется задать время в конкретном регионе независимо от системной настройки, это тоже нужно делать явно, а не полагаться на то, что все, кто будет читать конфигурацию позже, вспомнят исходный часовой пояс сервера на момент её написания.

Логи и приложения: где ещё вылезает несоответствие

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

Второй практический источник багов — приложения, которые сохраняют дату и время в базу данных без явного указания часового пояса, полагаясь на локальное время процесса на момент записи. Если сервер приложения переехал в другой дата-центр или изменил часовой пояс, а формат хранения дат в базе не был timezone-aware (например, тип TIMESTAMP WITHOUT TIME ZONE в PostgreSQL или обычный DATETIME в MySQL без явного хранения смещения), уже сохранённые исторические записи невозможно однозначно интерпретировать заново — неизвестно, в каком часовом поясе они были записаны изначально.

Практическая рекомендация, применяемая в большинстве современных приложений: хранить все временные метки в базе данных в UTC (используя типы, явно поддерживающие часовой пояс, если СУБД их предоставляет, либо просто договорившись хранить всё исключительно в UTC на уровне соглашения в коде), а конвертацию в местное время конкретного пользователя выполнять только на этапе отображения, уже зная нужный часовой пояс из профиля пользователя или его браузера. Это устраняет саму возможность путаницы, поскольку смещение из системного часового пояса сервера ни на каком этапе не участвует в хранении данных.

Сортировка и агрегация данных по датам — ещё одно место, где локаль (в данном случае, скорее, соглашение приложения, а не системная локаль ОС) способна создать неожиданный эффект: группировка событий "по дням" без явного указания часового пояса агрегации даёт разный результат в зависимости от того, чьё локальное время считается границей суток, особенно заметно для проектов с пользователями из разных часовых поясов.

Чек-лист настройки времени и локали на новом сервере

Шаг 1. Определите системный часовой пояс: UTC как безопасный дефолт для инфраструктуры из нескольких серверов и регионов, либо конкретный региональный часовой пояс, если сервер целиком обслуживает один регион и местное время реально нужно системным утилитам и логам.

Шаг 2. Установите выбранный часовой пояс через timedatectl set-timezone и убедитесь, что вывод timedatectl показывает System clock synchronized: yes — без работающей синхронизации времени (см. отдельную статью про NTP и Chrony) даже правильный часовой пояс не спасёт от постепенного расхождения системных часов.

Шаг 3. Сгенерируйте и установите нужную локаль через locale-gen и update-locale (или localectl на RHEL-семействе), проверив результат командой locale без аргументов в новой сессии.

Шаг 4. Проверьте, что crontab, systemd timers и любые встроенные планировщики приложения (например, очереди с отложенными задачами) интерпретируют время так, как ожидается, и явно задайте часовой пояс для конкретной задачи, если он должен отличаться от системного.

Шаг 5. Убедитесь, что приложение хранит временные метки в базе данных в UTC или в явно указанном часовом поясе, а не полагается неявно на системный часовой пояс процесса на момент записи.

Шаг 6. Синхронизируйте часовой пояс между всеми компонентами стека (веб-сервер, база данных, контейнеры, если они используются) — расхождение между ними усложняет сопоставление логов при разборе инцидентов.

Итог: маленькая настройка с большими последствиями при ошибке

Часовой пояс и локаль редко требуют внимания после первичной настройки сервера, но именно поэтому ошибки в них часто остаются незамеченными месяцами — до первого разбора инцидента с логами нескольких серверов, до первой ночной задачи, выполнившейся не в ту ночь, или до первого отчёта с перепутанными датами. UTC как системный часовой пояс и явное указание местного времени только там, где оно действительно нужно (в конкретной задаче cron или в коде отображения для пользователя), снимает большинство подобных проблем ещё до их появления.

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

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

Почему рекомендуют ставить UTC на сервере, а не местное время?

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

Как узнать текущий часовой пояс и локаль сервера?

Часовой пояс — командой timedatectl без аргументов, она покажет строку Time zone в выводе; текущую локаль — командой locale без аргументов, она выведет значения всех переменных LC_* и LANG, применяемых в текущей оболочке.

Нужно ли перезагружать сервер после смены часового пояса?

Нет, timedatectl set-timezone применяется немедленно и не требует перезагрузки, но уже запущенные процессы и демоны, которые прочитали часовой пояс при своём старте и закешировали его в памяти, могут не увидеть изменение до собственного перезапуска.

Что делать, если cron выполняет задачи не в то время, которое ожидалось?

Проверить часовой пояс, в котором работает сам демон cron, — обычно он определяется системным часовым поясом, но в некоторых системах и оболочках crontab можно явно задать переменную CRON_TZ или TZ прямо в файле crontab, и если она не совпадает с ожиданием администратора, задачи будут выполняться со сдвигом.

Влияет ли локаль на формат дат, которые видит пользователь на сайте?

Только если приложение явно берёт формат даты из системной локали, а не форматирует даты собственным кодом или библиотекой интернационализации; большинство современных веб-фреймворков форматируют даты независимо от локали ОС, но некоторые системные утилиты и часть кода на Perl, Python или PHP, вызывающая strftime, всё ещё могут зависеть от локали процесса.

Что означает ошибка "Cannot set LC_ALL to default locale" при подключении по SSH?

Локаль, которую пытается использовать клиентское SSH-соединение (обычно она передаётся с локальной машины пользователя через переменные окружения), не сгенерирована на сервере — либо нужно сгенерировать соответствующую локаль через locale-gen, либо отключить передачу локали клиентом, либо запретить её приём на стороне sshd.

Можно ли использовать разные часовые пояса для разных сервисов на одном сервере?

Системный часовой пояс общий для всех процессов, но отдельный процесс может переопределить его для себя через переменную окружения TZ, не меняя часовой пояс остальной системы, — это часто применяют для отдельного планировщика или сервиса отчётности, которому нужно местное время конкретного региона.

Как переключить локаль без переустановки системы?

Сгенерировать нужную локаль через locale-gen (если она ещё не сгенерирована), затем установить её системной локалью по умолчанию через update-locale, и после этого перелогиниться или перезапустить процессы, которые должны подхватить новую локаль, поскольку уже запущенные процессы обычно продолжают работать со старым окружением.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.