🕐
← Назад к руководствам

Преобразование часовых поясов Unix-времени: практическое руководство

· Теги: timezone, dst, utc, time-conversion, unix-timestamp, daylight-saving, epoch

Почему часовой пояс важен для Unix-времени

Сами по себе Unix-метки времени не зависят от часового пояса — число 1785292800 означает один и тот же момент везде. Сложность возникает при преобразовании этого момента в человекочитаемое местное время для отображения, ведения журналов или анализа данных.

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

UTC и местное время: понимание разницы

UTC (Всемирное координированное время)

UTC — это основной стандарт времени. Он никогда не меняется для летнего времени и одинаков в любой точке Земли. Unix-время определено в UTC.

Местное время

Местное время — это UTC, скорректированное для конкретного географического региона. Оно может отличаться от UTC на фиксированное смещение (например, UTC+8 для Китайского стандартного времени) или переменное смещение (например, Восточное время переключается между UTC-5 и UTC-4 для летнего времени).

Проблема смещения

Одна и та же Unix-метка времени даёт разное местное время в зависимости от местоположения наблюдателя:

| Метка времени | UTC | Нью-Йорк (EST) | Токио (JST) | Лондон (BST) | |-----------|-----|----------------|-------------|--------------| | 1785292800 | 2026-07-19 00:00 | 2026-07-18 20:00 | 2026-07-19 09:00 | 2026-07-19 01:00 | | 1785379200 | 2026-07-19 23:59 | 2026-07-19 19:59 | 2026-07-20 08:59 | 2026-07-20 00:59 |

Летнее время (DST)

Что такое летнее время?

Летнее время — это практика перевода часов вперёд в летние месяцы, чтобы вечернее светлое время длилось дольше. Часы «переводятся вперёд» (теряется один час) весной и «переводятся назад» (приобретается один час) осенью.

Влияние на преобразование меток времени

Летнее время создаёт переменное смещение между местным временем и UTC. Это означает:

  1. Одно и то же местное время может соответствовать двум разным меткам времени (во время перехода «назад», час 1:00 наступает дважды)
  2. Некоторые значения местного времени не существуют (во время перехода «вперёд», например, 2:00 никогда не наступает — часы сразу переходят на 3:00)

Пример: неоднозначный час

В часовом поясе Восточного времени США, в первое воскресенье ноября в 2:00, часы переводятся назад на 1:00. Это означает:

from datetime import datetime, timezone
import pytz

eastern = pytz.timezone("America/New_York")

# Первое наступление 1:00 (EDT, UTC-4)
first = eastern.localize(datetime(2026, 11, 1, 1, 0), is_dst=True)
print(first.timestamp())
# Some timestamp value

# Второе наступление 1:00 (EST, UTC-5) = на 3600 секунд позже!
second = eastern.localize(datetime(2026, 11, 1, 1, 0), is_dst=False)
print(second.timestamp())
# first.timestamp() + 3600

Всегда аккуратно обрабатывайте неоднозначный час перехода назад в своих приложениях. Использование флагов is_dst/ambiguous в Python или эквивалентных опций в других языках предотвращает скрытые ошибки.

Преобразование между часовыми поясами

Использование нашего онлайн-инструмента

Самый простой подход для разовых преобразований — наш Конвертер Unix-времени, который отображает результаты сразу в нескольких часовых поясах.

Использование командной строки Linux

# Отображение метки времени в нескольких часовых поясах
TZ="America/New_York" date -d @1785292800
TZ="Europe/London"    date -d @1785292800
TZ="Asia/Tokyo"       date -d @1785292800

# С пользовательским форматом ISO
TZ="UTC" date -d @1785292800 +"%Y-%m-%d %H:%M:%S %Z"
# Output: 2026-07-19 00:00:00 UTC

TZ="Asia/Shanghai" date -d @1785292800 +"%Y-%m-%d %H:%M:%S %Z"
# Output: 2026-07-19 08:00:00 CST

Использование Python

from datetime import datetime
from zoneinfo import ZoneInfo  # Python 3.9+

ts = 1785292800

# Преобразование в несколько часовых поясов
timezones = ["America/New_York", "Europe/London", "Asia/Tokyo", "Australia/Sydney"]

for tz_name in timezones:
    tz = ZoneInfo(tz_name)
    dt = datetime.fromtimestamp(ts, tz=tz)
    print(f"{tz_name}: {dt.strftime('%Y-%m-%d %H:%M:%S %Z')}")

Использование JavaScript

const ts = 1785292800;
const date = new Date(ts * 1000);

const timezones = [
    "America/New_York",
    "Europe/London",
    "Asia/Tokyo",
    "Australia/Sydney"
];

for (const tz of timezones) {
    const str = date.toLocaleString("en-US", {
        timeZone: tz,
        timeZoneName: "short",
    });
    console.log(`${tz}: ${str}`);
}

Использование Go

package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Unix(1785292800, 0)
    
    timezones := []string{
        "America/New_York",
        "Europe/London",
        "Asia/Tokyo",
        "Australia/Sydney",
    }
    
    for _, tz := range timezones {
        loc, _ := time.LoadLocation(tz)
        fmt.Printf("%s: %s\n", tz, t.In(loc).Format("2006-01-02 15:04:05"))
    }
}

Распространённые шаблоны преобразования часовых поясов

Преобразование серверных журналов в местное время

Серверные журналы обычно записывают метки времени в UTC. При их анализе преобразуйте в свой местный часовой пояс:

# Чтение файла журнала и отображение меток времени в тихоокеанском времени
while IFS= read -r line; do
    if [[ $line =~ ^([0-9]+) ]]; then
        ts="${BASH_REMATCH[1]}"
        TZ="America/Los_Angeles" date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
        echo " $line"
    fi
done < server.log

Планирование событий между часовыми поясами

При обмене временем событий между часовыми поясами всегда указывайте время в UTC или передавайте Unix-метку напрямую. Это устраняет неоднозначность:

  • «Встреча в 1785292800» — однозначно
  • «Встреча в 9:00 EST» — становится неоднозначным во время перехода летнего времени
  • «Встреча в 9:00 America/New_York» — лучше, но всё равно требует знания статуса летнего времени

Хранение меток времени в базах данных

-- Всегда храните саму метку времени (не зависящую от часового пояса)
INSERT INTO events (occurred_at, user_id) VALUES (1785292800, 42);

-- ИЛИ храните с явным столбцом UTC-времени
INSERT INTO events (occurred_at_utc, user_id) 
VALUES ('2026-07-19 00:00:00+00', 42);

Краткий свод лучших практик

  1. Храните в UTC, преобразуйте для отображения — Никогда не храните местное время в базах данных
  2. Используйте имена часовых поясов IANA (например, America/New_York) вместо сокращений (EST, PST) — сокращения неоднозначны и не учитывают летнее время
  3. Явно обрабатывайте летнее время — Используйте библиотеки с поддержкой часовых поясов; никогда не добавляйте/вычитайте часы вручную
  4. Всегда передавайте информацию о часовом поясе — При приёме дат от пользователей собирайте часовой пояс, а не только смещение
  5. Тестируйте граничные даты — Проверяйте логику преобразования на датах перехода летнего времени (как весной, так и осенью), чтобы выявить ошибки на ранних этапах

База данных часовых поясов

Данные о часовых поясах вашей системы поступают из Базы данных часовых поясов IANA (также называемой базой данных Олсона), которая обновляется несколько раз в год при изменении правил летнего времени правительствами. Поддерживайте свою систему в актуальном состоянии:

# Debian / Ubuntu
sudo apt update && sudo apt install tzdata

# macOS
# Автоматически обновляется через обновления ПО

# Проверьте версию вашей базы данных
zdump -v /etc/localtime | head -1

Воспользуйтесь нашим Конвертером Unix-времени для быстрых преобразований с учётом часовых поясов во всех основных часовых поясах.