Unix timestamp в JavaScript, Python, PHP и Go — шпаргалка по коду

Unix timestamp — это количество секунд, прошедших с 1 января 1970 года, 00:00:00 UTC. Идея простая, реализация кажется одинаковой — пока не выяснится, что JavaScript работает с миллисекундами, в Python есть несколько функций, которые возвращают чуть разные вещи, а в PHP форматирование зависит от настроек таймзоны и регулярно застает людей врасплох.

Для быстрых преобразований используйте Unix Timestamp Converter. А эта статья — справочник на случай, когда нужно работать с timestamp программно на выбранном языке.

JavaScript

Date.now() в JavaScript возвращает миллисекунды, а не секунды. Это самый частый источник ошибок, когда фронтенд на JS общается с бэкендом, который ожидает секунды.

// Текущий timestamp в миллисекундах
const ms = Date.now();                    // например: 1712505600000

// Текущий timestamp в секундах (целое)
const secs = Math.floor(Date.now() / 1000);  // например: 1712505600

// Из объекта Date
const d = new Date();
const secs2 = Math.floor(d.getTime() / 1000);

// Разобрать Unix timestamp (секунды) в Date
const ts = 1712505600;
const date = new Date(ts * 1000);         // умножаем на 1000, чтобы получить ms

// Формат ISO 8601
const iso = date.toISOString();           // "2024-04-07T16:00:00.000Z"

// Отдельные компоненты (UTC)
const year = date.getUTCFullYear();
const month = date.getUTCMonth() + 1;    // 0-index, добавляем 1
const day = date.getUTCDate();
const hours = date.getUTCHours();
const minutes = date.getUTCMinutes();

// Преобразовать строку даты в timestamp
const from_string = Math.floor(new Date("2024-04-07T16:00:00Z").getTime() / 1000);

Частая ошибка: new Date(timestamp) без умножения на 1000 интерпретирует секундный timestamp как миллисекунды и дает дату в 1970 году. Всегда умножайте на 1000, когда создаете Date из timestamp в секундах.

Истечение токена: `js const expiresAt = Math.floor(Date.now() / 1000) + 86400; // 24 часа от текущего момента const isExpired = Math.floor(Date.now() / 1000) > expiresAt; `

Python

В Python по умолчанию используются секунды. time.time() возвращает float; используйте int() или //, чтобы получить целое.

import time
from datetime import datetime, timezone

# Текущий timestamp (секунды, float)
ts_float = time.time()             # например: 1712505600.123456

# Текущий timestamp (секунды, int)
ts_int = int(time.time())          # например: 1712505600

# Преобразовать timestamp в datetime (UTC-aware)
ts = 1712505600
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
# datetime(2024, 4, 7, 16, 0, tzinfo=timezone.utc)

# Формат ISO 8601
iso = dt.isoformat()               # "2024-04-07T16:00:00+00:00"

# Naive datetime (локальное время — избегайте в продакшене)
dt_local = datetime.fromtimestamp(ts)

# Преобразовать datetime в timestamp
from datetime import datetime, timezone
dt = datetime(2024, 4, 7, 16, 0, 0, tzinfo=timezone.utc)
ts_back = int(dt.timestamp())      # 1712505600

# 24 часа от текущего момента
expires_at = int(time.time()) + 86400

Частая ошибка: datetime.fromtimestamp() без tz=timezone.utc использует локальное системное время. На сервере в UTC это может «случайно» работать, но на сервере в другом поясе или в пользовательском коде добавляет смещение. Почти всегда лучше передавать tz=timezone.utc, если вы явно не хотите локальное время.

# Плохо (зависит от таймзоны системы)
datetime.fromtimestamp(1712505600)

# Хорошо (всегда UTC)
datetime.fromtimestamp(1712505600, tz=timezone.utc)

PHP

time() в PHP возвращает секунды — как и принято в Unix. Самое важное: функции форматирования дат в PHP зависят от настройки date.timezone в php.ini. Если она неверна, форматированные даты будут «съезжать».

<?php

// Текущий timestamp (секунды)
$ts = time();                          // например: 1712505600

// Преобразовать timestamp в форматированную дату (UTC)
echo date('Y-m-d H:i:s', $ts);        // вывод зависит от настройки таймзоны

// Принудительно вывести UTC независимо от php.ini
echo gmdate('Y-m-d H:i:s', $ts);      // "2024-04-07 16:00:00"

// ISO 8601 (UTC)
echo gmdate('c', $ts);                 // "2024-04-07T16:00:00+00:00"
// Или вручную:
echo gmdate('Y-m-d\TH:i:s\Z', $ts);   // "2024-04-07T16:00:00Z"

// Преобразовать строку даты в timestamp (UTC)
$ts2 = strtotime('2024-04-07 16:00:00 UTC');

// DateTime — для более точного контроля
$dt = new DateTime('@' . $ts);         // префикс @ означает Unix timestamp
$dt->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('Y-m-d H:i:s');

// 24 часа от текущего момента
$expires_at = time() + 86400;

// Проверить, истек ли timestamp
$is_expired = time() > $expires_at;

Частая ошибка: date() использует локальную таймзону из date.timezone. gmdate() всегда использует UTC. В веб‑приложении обычно лучше применять gmdate() для timestamp и полей API, если нет осознанной причины использовать локальное время.

PHP 8.x с DateTimeImmutable: `php $dt = new DateTimeImmutable('@' . $ts, new DateTimeZone('UTC')); echo $dt->format(DateTimeInterface::ATOM); // "2024-04-07T16:00:00+00:00" `

Go

Пакет time в Go аккуратный и явно работает с таймзонами. Нулевое значение time.Time — это 1 января 1 года (а не Unix epoch), поэтому проверки «на ноль» отличаются от многих других языков.

package main

import (
    "fmt"
    "time"
)

func main() {
    // Текущий Unix timestamp (секунды)
    ts := time.Now().Unix()               // int64

    // Текущий Unix timestamp (миллисекунды)
    ts_ms := time.Now().UnixMilli()       // int64

    // Текущий Unix timestamp (наносекунды)
    ts_ns := time.Now().UnixNano()        // int64

    // Преобразовать Unix timestamp в time.Time (UTC)
    t := time.Unix(1712505600, 0).UTC()
    fmt.Println(t)                        // 2024-04-07 16:00:00 +0000 UTC

    // Формат ISO 8601
    iso := t.Format(time.RFC3339)         // "2024-04-07T16:00:00Z"

    // Разобрать строку ISO 8601 в timestamp
    parsed, _ := time.Parse(time.RFC3339, "2024-04-07T16:00:00Z")
    ts2 := parsed.Unix()                  // 1712505600

    // 24 часа от текущего момента
    expires_at := time.Now().Add(24 * time.Hour).Unix()

    // Проверка истечения
    is_expired := time.Now().Unix() > expires_at

    _ = ts
    _ = ts_ms
    _ = ts_ns
    _ = ts2
    _ = is_expired
    fmt.Println(expires_at)
    _ = iso
}

Ключевое отличие: time.Unix(ts, 0) принимает два аргумента — секунды и наносекунды. Для обычных Unix timestamp параметр наносекунд почти всегда равен 0.

Частая ошибка: забыть .UTC() после time.Unix() — тогда время окажется в локальной таймзоне машины. В продакшене это часто «нормально», если сервер в UTC, но в разных окружениях поведение может отличаться. Явно добавляйте .UTC() для надежности.

Сравнение по языкам

ЗадачаJavaScriptPythonPHPGo
Текущий timestamp (секунды)Math.floor(Date.now()/1000)int(time.time())time()time.Now().Unix()
Единицы по умолчаниюМиллисекундыСекундыСекундыСекунды (есть и nano)
Timestamp → датаnew Date(ts * 1000)datetime.fromtimestamp(ts, tz=utc)new DateTime('@'.$ts)time.Unix(ts, 0).UTC()
Формат ISO 8601.toISOString().isoformat()gmdate('c', $ts).Format(time.RFC3339)
Таймзона по умолчаниюUTCСистемная/локальнаяНастройка php.iniСистемная/локальная

Как отличить секунды от миллисекунд

Если вы получили timestamp и не уверены, в секундах он или в миллисекундах:

  • 10 цифр: секунды (например, 1712505600 = апрель 2024)
  • 13 цифр: миллисекунды (например, 1712505600000)

Граница: любое значение больше 9,999,999,999 (10 миллиардов) с большой вероятностью в миллисекундах. Unix timestamp в секундах превысил 1,700,000,000 в сентябре 2023 и не достигнет 10,000,000,000 до ноября 2286 года.

Unix Timestamp Converter автоматически распознает формат и показывает представление и в секундах, и в миллисекундах.