Конвертер Unix-времени
Переведите Unix-метку времени в дату в любом часовом поясе и обратно: секунды или миллисекунды определяются сами, плюс ISO 8601 и сколько времени прошло.
Что такое Unix-метка времени
Unix-метка времени — её также называют epoch-временем или POSIX-временем — это одно число, считающее, сколько секунд прошло с 00:00:00 UTC 1 января 1970 года, момента, известного как Unix-эпоха. Поскольку это одно целое число, без часового пояса, без календаря и без форматирования, именно к этому формату обращаются компьютеры всякий раз, когда момент времени нужно сохранить, отсортировать, сравнить или передать по сети. Это то, что стоит за столбцом «created_at» в вашей базе данных, за полями «iat» и «exp» в JWT, за mtime файла и за метками времени почти в любом журнале, который вам доведётся читать.
Плата за это — голое число ничего не говорит человеку. 1716197600 — вполне корректный момент, но с первого взгляда не понять, прошлый ли это вторник или три года назад. Именно этот перевод, в обе стороны, и делает данный инструмент.
Секунды или миллисекунды — двусмысленность, которая кусается
Исходное соглашение Unix считает целые секунды, и именно это возвращают date +%s в оболочке, time() в PHP и time.time() в Python после отбрасывания дробной части. JavaScript, Java и многие другие считают миллисекунды: Date.now() возвращает число в тысячу раз больше. И то и другое называют «меткой времени», а их смешение — одна из самых частых ошибок с датами вообще.
Сбой здесь тихий, а не громкий. Прочитайте значение в миллисекундах как секунды — и дата улетит на десятки тысяч лет вперёд; прочитайте значение в секундах как миллисекунды — и всё схлопнется в январь 1970 года. Ни в том, ни в другом случае ошибки не будет: вы просто получите неверную дату, выглядящую как настоящая.
Этот инструмент угадывает по порядку величины числа, а затем сообщает вам, что именно он угадал, прямо рядом с результатом. Сегодняшние epoch-секунды состоят из десяти цифр, а миллисекунды — из тринадцати, поэтому догадка почти всегда верна. Но «почти» недостаточно для значения, которое вы вот-вот вставите в отчёт об ошибке, — поэтому выбранная трактовка всегда на виду и всегда в одном щелчке от переключения.
Часовые пояса, UTC и почему «местное» — скользкое понятие
У Unix-метки времени нет часового пояса. Она обозначает момент: 1716197600 — это 2024-05-20T09:33:20Z, и этот же самый момент одновременно есть 10:33 в Лондоне, 12:33 в Иерусалиме и 18:33 в Токио, потому что в тот день в Лондоне и Иерусалиме действует летнее время, а в Японии его нет вовсе. Часовой пояс не входит в значение; это линза, через которую вы на него смотрите.
Поэтому инструмент показывает сразу несколько линз. UTC — нейтральная точка отсчёта, с которой согласны все серверы и журналы. Ваше местное время — то, о котором сообщает ваше собственное устройство; оно показано с именем пояса (например, Europe/Berlin), чтобы вы всегда знали, какая линза его дала: определение происходит в вашем браузере, поэтому посетитель из Берлина видит берлинское время, а из Токио — токийское. Третья строка — любой пояс на ваш выбор из полной базы IANA, и именно она нужна, когда вы читаете журнал сервера, стоящего где-то ещё.
- UTC — точка отсчёта, с которой согласны все системы, и то, что правильно хранить и записывать в журналы.
- Местное — тот же момент, каким его видит ваше устройство, с пометкой об определённом поясе.
- Пояс на ваш выбор — для чтения журналов и трассировок с машин в других местах.
- ISO 8601 — текстовый формат обмена, например 2024-05-20T09:33:20.000Z.
- Относительно — «3 часа назад», чтобы быстро понять, насколько это свежее.
Смещения показаны рядом с каждым временем (+03:00, -04:00), потому что они не постоянны: большинство поясов сдвигаются на час из-за перехода на летнее время, так что один и тот же пояс может давать разные смещения в разное время года. Дата вблизи перехода — как раз то место, где ручные подсчёты дают сбой.
Работа с epoch-временем на практике
В каждом языке и в каждой оболочке свой способ получать и читать epoch-значения. Эти стоит запомнить:
date +%s # оболочка: текущее время в секундах date -d @1716197600 # оболочка (GNU): из секунд в дату Date.now() # JavaScript: текущее время в МИЛЛИсекундах new Date(1716197600 * 1000) # JavaScript: из секунд в Date time.time() # Python: секунды, как дробное число datetime.fromtimestamp(1716197600, tz=timezone.utc) SELECT EXTRACT(EPOCH FROM now()) -- PostgreSQL: секунды
Правило, избавляющее от большей части боли с датами: храните и передавайте моменты в UTC — либо целым epoch-числом, либо строкой ISO 8601 — и переводите в местный пояс только в самый последний момент, когда действительно показываете их человеку. Слишком раннее форматирование — это то, как ошибка часового пояса запекается в ваши данные вместо того, чтобы остаться в слое отображения.
Ещё одно, о чём стоит знать: знаковый 32-битный счётчик секунд исчерпывается 19 января 2038 года — «проблема 2038 года». Современные системы используют 64-битные значения и в безопасности, но старые встраиваемые устройства и унаследованные столбцы баз данных — как раз те места, где с ней ещё можно столкнуться.
Что такое эпоха и почему не всякая метка времени отсчитывается от 1970 года
Эпоха в этом смысле — просто выбранный ноль, момент, от которого счётчик по определению начинает счёт. Unix-эпоха — это 1 января 1970 года, 00:00:00 UTC, и она выбрана потому, что это удобная круглая дата, а не потому, что откуда-то выводится: ничто в самом формате не требует именно этого дня. Ранний Unix считал шестидесятые доли секунды от куда более близкого нуля, и руководство третьего издания прямо сказало, почему так не могло продолжаться: тридцать два бита шестидесятых долей гарантируют кризис каждые 2,26 года, то есть примерно каждые 828 дней. Целых секунд в тех же тридцати двух битах хватает на сто тридцать шесть лет, или на шестьдесят восемь, если счётчик знаковый, — это и есть дата 2038 года выше.
Эта предыстория и есть причина проверять длинное число, прежде чем ему доверять. Другие системы считают от других нулей и с другим разрешением, и прочитать одно из них как Unix-секунды — значит промахнуться не на несколько часов, а на века. Вот те, что встречаются чаще всего:
- Windows FILETIME — стонаносекундные тики с 1 января 1601 года UTC. Разделите на десять миллионов и вычтите 11644473600, чтобы получить Unix-секунды; момент 1716197600, который используется во всём этом руководстве, там равен 133606712000000000.
- .NET DateTime.Ticks — тот же стонаносекундный тик, но отсчитываемый от начала 1 года. Сама Unix-эпоха приходится на 621355968000000000 тиков, и это то число, которое вычитают перед делением.
- Опорная дата Apple — секунды с 1 января 2001 года UTC, её используют Cocoa и Core Data. Прибавьте 978307200, чтобы получить Unix-секунды: 1716197600 там равно 737890400.
- Серийные номера Excel — дни, а не секунды, и отсчёт идёт с 30 декабря 1899 года, потому что Excel считает 1900 год високосным, каким он не был.
- Время GPS — секунды с 6 января 1980 года, отсчитываемые без единого пропуска секунды координации, так что время GPS и UTC больше не совпадают.
Последний пункт указывает на то, что верно и для самого значения Unix: это не показание секундомера. POSIX определяет его как значение, приближающее число секунд, прошедших с эпохи, и требует, чтобы каждый без исключения день учитывался ровно 86400 секундами, — то есть вставленные в UTC секунды координации не считаются вовсе. Разность двух Unix-меток времени — это число календарных секунд между ними, а не число действительно прошедших, и значение лучше всего понимать как кодировку календарного показания в UTC. По этой же причине ни одна метка времени не обозначает секунду координации: в кодировке для неё просто нет места.
Как из даты получить epoch-значение: оболочка, JavaScript и Python
Блок выше превращает epoch-значение в нечто читаемое. Обратное направление — дата, которая у вас уже есть, текстом или набором чисел, превращаемая в epoch-значение, — как раз то место, где живут ошибки часовых поясов, потому что каждый из этих языков молча предположит пояс, если текст его не называет. Вот одна и та же задача тремя способами, на моменте 2024-05-20T09:33:20Z из этого руководства. Строки оболочки — это date из GNU; date в BSD и macOS принимает другие ключи.
date -u -d '2024-05-20 09:33:20' +%s # 1716197600 — ключ -u читает текст как UTC date -d '2024-05-20 09:33:20 UTC' +%s # то же самое, но пояс назван в самом тексте date -d '2024-05-20 09:33:20' +%s # ни то ни другое: пояс вашей машины
Date.parse('2024-05-20T09:33:20Z') / 1000 // 1716197600 — именно Z делает это UTC
new Date('2024-05-20T09:33:20Z').getTime() // тот же момент в миллисекундах
Date.parse('2024-05-20 09:33:20') // без Z: пояс вашей машины, другой моментfrom datetime import datetime, timezone
int(datetime(2024, 5, 20, 9, 33, 20, tzinfo=timezone.utc).timestamp()) # 1716197600 — с часовым поясом
int(datetime.fromisoformat('2024-05-20T09:33:20+00:00').timestamp()) # то же самое, разобранное из строки
int(datetime(2024, 5, 20, 9, 33, 20).timestamp()) # наивный: пояс вашей машиныСхема во всех трёх одна: назовите пояс — или унаследуете тот, на который настроена машина. Число, верное на вашем ноутбуке и ошибающееся на несколько часов на ноутбуке коллеги, — это почти всегда именно оно, и потому инструмент выше показывает UTC и ваше местное время рядом, а не выбирает одно за вас. Если число у вас уже есть и вы хотите проверить его глазами, вставьте его в поле вверху этой страницы.
Частые вопросы
- Как инструмент понимает, секунды у меня или миллисекунды?
- По порядку величины: значения примерно до 1e11 читаются как секунды, большие — как миллисекунды. Сегодня это чётко отделяет десятизначные секунды от тринадцатизначных миллисекунд. Трактовка показана рядом с результатом, и её можно переключить одним щелчком, так что догадка никогда от вас не скрыта.
- Какой часовой пояс считается «местным»?
- Тот, о котором сообщает ваше собственное устройство; он определяется в браузере и показан по имени, чтобы не оставалось сомнений. Это ваш пояс, а не пояс сайта: посетитель из Берлина видит берлинское время, а из Токио — токийское.
- Можно ли перевести дату обратно в метку времени?
- Да. Одно и то же поле принимает оба направления: введите число — получите дату; введите дату вида 2024-05-20 или 2024-05-20T09:33:20Z — получите epoch-значение. Никакой режим переключать не нужно.
- Работает ли он с датами до 1970 года?
- Да. Метки времени до эпохи просто отрицательные — -86400 это 31 декабря 1969 года — и отрицательные значения принимаются и преобразуются как обычно.
- Почему моя метка времени показывает не ту дату, которую я ожидал?
- Почти всегда по одной из двух причин: трактовка секунды/миллисекунды не та, которую вы предполагали (посмотрите на подпись и переключите её), либо вы сравниваете значение в UTC с ожиданием в местном времени. Инструмент показывает обе строки рядом, чтобы вы увидели, какой из случаев ваш.
- Что такое проблема 2038 года?
- Системы, хранящие epoch-секунды в знаковом 32-битном целом, переполняются 19 января 2038 года и переходят к отрицательному числу, давая даты в 1901 году. Всё, что использует 64-битные значения — то есть почти всё современное — не затронуто, но унаследованные встраиваемые системы и старые столбцы баз данных всё ещё могут быть в зоне риска.
- Почему моя метка времени состоит из восемнадцати цифр?
- Потому что это, скорее всего, не Unix-метка времени. Unix-секунды сегодня занимают десять цифр, а миллисекунды — тринадцать; восемнадцать — это вид стонаносекундного тика, который Windows FILETIME отсчитывает от 1601 года, а .NET — от начала 1 года. Шестнадцать цифр — другой частый случай: тот же момент в микросекундах. Раздел об эпохах выше даёт число, которое нужно вычесть в каждом случае.
- Как в Python перевести дату в Unix-метку времени?
- Создайте datetime с часовым поясом — то есть несущий tzinfo — вызовите у него метод timestamp и отбросьте дробную часть до целого. Строка есть в блоке кода выше, и тот же раздел показывает ту же задачу в оболочке и в JavaScript. Вся трудность именно в tzinfo: опустите его — и Python прочитает ваши числа как местное время машины и вернёт другое значение, ничего вам не сказав.
- Отправляется ли куда-нибудь введённая мной метка времени?
- Нет. Разбор, преобразование и форматирование выполняются целиком в вашем браузере, с опорой на собственную поддержку дат и часовых поясов в платформе. Ничто из набранного вами не покидает ваше устройство.
Похожие инструменты
- Калькулятор chmod
Переводит права файла между восьмеричной, символьной формой и флажками.
- Калькулятор CIDR / подсетей
Разберите сеть, проверьте вхождение, разделите её.
- Разбор выражений cron
Прочитать выражение cron и увидеть, когда оно сработает.
- Какой у меня IP
Ваши публичные IPv4 и IPv6 — и тот, что выбрал браузер.