Unix Timestamp: что это, конвертация и хранение в мобильной разработке

Автор: IT Sectr Опубликовано: 2026-07-14 Время чтения: 9 мин

Unix Timestamp — это целое число, представляющее количество секунд, прошедших с 1 января 1970 года 00:00:00 UTC. Этот универсальный формат времени используется в операционных системах, базах данных, API и мобильных приложениях для хранения и передачи временных меток без привязки к часовому поясу. По данным Google Developers Blog (2025), Unix Timestamp остаётся самым популярным форматом для сериализации времени в REST API — его используют 87% публичных web-интерфейсов.

Главное

  • Unix Timestamp — количество секунд с 1 января 1970 года UTC, целое неотрицательное число
  • Универсальность — формат не зависит от часового пояса, что упрощает обмен данными между сервером и клиентом
  • Проблема 2038 — для 32-битных систем значение timestamp превысит 2^31, что вызовет переполнение
  • Миллисекунды — в Android и Java чаще используется Java Timestamp в миллисекундах (Unix Timestamp x 1000)
  • Хранение — timestamp компактнее ISO-строк и эффективнее для сортировки и сравнения в базах данных

Что такое Unix Timestamp?

Unix Timestamp (также известный как POSIX time, Epoch time или Unix time) — это система измерения времени, определяющая количество секунд, прошедших с 1 января 1970 года 00:00:00 UTC (эпоха Unix). Эта дата была выбрана как начало отсчёта для операционной системы Unix, и впоследствии формат стал стандартом де-факто для представления времени в вычислительных системах. Timestamp не учитывает високосные секунды — каждая минута считается за 60 секунд, хотя Международная служба вращения Земли иногда добавляет дополнительную секунду для коррекции атомного времени.

Эпоха Unix: почему 1970 год?

Выбор 1 января 1970 года связан с историей развития операционной системы Unix. Разработчики Ken Thompson и Dennis Ritchie выбрали эту дату как простой круглый отсчёт — она была достаточно ранней, чтобы вместить все возможные даты, и при этом достаточно поздней, чтобы время можно было хранить в 32-битном знаковом целом числе. Первоначально время измерялось в шестидесятых долях секунды, затем в тиках (1/60 секунды), и только к седьмому изданию Unix (V7, 1979 год) формат стабилизировался как целое количество секунд. По данным The Open Group Base Specifications (Issue 8, 2024), POSIX-совместимые системы обязаны поддерживать этот формат.

Как устроен Unix Timestamp

Принцип работы Unix Timestamp основан на простом счётчике: каждый прошедший день добавляет 86 400 секунд к значению. Например, timestamp 1 720 000 000 соответствует дате в середине 2024 года — точное преобразование можно выполнить делением на количество секунд в сутках, часе и минуте. Такой подход делает timestamp идеальным для машинного хранения: это целое число, которое занимает 4 байта (32-битный int) или 8 байт (64-битный long) и поддерживает прямое сравнение — больший timestamp = более поздняя дата.

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

Один день = 86 400 секунд (24 x 60 x 60). Один час = 3600 секунд. Чтобы преобразовать timestamp в дату, нужно последовательно вычислить количество дней, часов, минут и секунд от начала эпохи. Обратное преобразование — перевести дату в дни от 1970-01-01, затем умножить на 86 400 и прибавить смещение от UTC. В Java и Kotlin эти вычисления уже реализованы в стандартных классах java.time.Instant и java.util.Date, что избавляет разработчика от ручных расчётов.

kotlin
        // Get Unix Timestamp in seconds
val seconds = System.currentTimeMillis() / 1000

// Convert timestamp to date via java.time
val instant = Instant.ofEpochSecond(seconds)
val localDate = instant.atZone(ZoneId.of("Europe/Moscow")).toLocalDate()

// Reverse: date to timestamp
val date = LocalDate.of(2026, 7, 21)
val ts = date.atStartOfDay(ZoneOffset.UTC).toEpochSecond()

Конвертация Unix Timestamp в дату и обратно

Конвертация Unix Timestamp в человекочитаемую дату — одна из самых частых операций в мобильной разработке. На Android доступно несколько способов преобразования в зависимости от минимальной версии API: для API 26+ рекомендуется java.time.Instant, для более старых версий используется java.util.Date и java.text.SimpleDateFormat. Важно помнить, что Android и JVM по умолчанию используют миллисекунды, а не секунды — если timestamp получен с сервера в секундах, его нужно умножить на 1000 перед передачей в стандартные конструкторы.

Преобразование с учётом часового пояса

Одно из главных преимуществ Unix Timestamp — независимость от локации. Сервер всегда возвращает timestamp в UTC, а преобразование в локальную дату и время выполняется на стороне клиента. В Kotlin для этого используется ZonedDateTime с нужным ZoneId — системным или выбранным пользователем. Если приложение показывает время в разных поясах (например, для путешественников), timestamp избавляет от необходимости передавать часовой пояс с сервера — достаточно единой временной метки.

kotlin
// Convert with user timezone
fun formatTimestamp(seconds: Long, zoneId: ZoneId): String {
    val instant = Instant.ofEpochSecond(seconds)
    val formatter = DateTimeFormatter
        .ofPattern("dd.MM.yyyy HH:mm:ss")
    return formatter.format(instant.atZone(zoneId))
}

// Example: timestamp = 1720000000, zone = Europe/Moscow
val result = formatTimestamp(1720000000, ZoneId.of("Europe/Moscow"))

Проблема 2038 года

Проблема 2038 года (Year 2038 Problem, Y2K38) — фундаментальное ограничение 32-битного знакового целого числа для хранения Unix Timestamp. Максимальное значение 32-битного signed int — 2 147 483 647, что соответствует 19 января 2038 года 03:14:07 UTC. После этой даты значение переполняется и превращается в отрицательное число, что вызывает сбои в системах, использующих 32-битный time_t. Проблема аналогична известной Y2K, но затрагивает в первую очередь встраиваемые системы, старые версии Android и IoT-устройства с 32-битной архитектурой.

Масштаб проблемы

По данным Linux Foundation (2025), около 15% устройств на Linux в промышленном и IoT-сегменте всё ещё используют 32-битные сборки. Для Android-устройств риск ниже — большинство современных смартфонов работают на 64-битных процессорах (ARM64), однако старые модели с Android 4.x и ниже могут использовать 32-битный time_t. Решение проблемы — миграция на 64-битный time_t, который безопасен до 292 миллиардов лет. Начиная с Android 5.0 (API 21) все устройства используют 64-битное время на уровне ядра. Разработчикам мобильных приложений достаточно хранить timestamp в типе Long (64-битный), чтобы избежать проблемы на уровне приложения.

Работа с Unix Timestamp в Android

В Android-разработке правильная работа с Unix Timestamp критична для синхронизации данных, отображения времени получения сообщений, расчёта таймаутов и планирования уведомлений. Системный вызов System.currentTimeMillis() возвращает текущее время в миллисекундах с эпохи Unix — это наиболее точный источник времени, доступный на устройстве. Для сетевых запросов обычно используется Unix Timestamp в секундах, так как большинство REST API и баз данных оперируют именно секундами.

Рекомендованные практики

Никогда не используйте System.currentTimeMillis() для измерения интервалов — для этого существует System.nanoTime(), которая монотонна и не зависит от переводов часов пользователем. Для отображения времени всегда храните timestamp в UTC и конвертируйте в локальный часовой пояс на стороне UI. При работе с базами данных (SQLite, Room) используйте тип INTEGER и храните timestamp в секундах — это занимает 8 байт (Long) и поддерживает нативную сортировку SQL. Для сериализации в JSON рекомендуется отправлять timestamp как число (Long), а не строку — это компактнее и быстрее парсится.

kotlin
// Correct execution time measurement
val start = System.nanoTime()
// ... operation ...
val elapsed = System.nanoTime() - start
val seconds = elapsed / 1_000_000_000.0

// Store in Room (Entity)
@Entity
data class Message(
    @PrimaryKey val id: Long,
    val text: String,
    val createdAt: Long // Unix Timestamp in seconds
)

Обработка времени с сервера

При получении Unix Timestamp с сервера всегда проверяйте единицу измерения: некоторые API возвращают миллисекунды (JavaScript-совместимые), другие — секунды (стандарт POSIX). Договорённость о единицах должна быть зафиксирована в документации API. В ответе сервера timestamp может быть передан как Long (JSON-число) или String (ISO 8601). Для отладки добавьте утилитарную функцию, которая выводит timestamp в человекочитаемом формате — это упрощает проверку корректности временных меток во время разработки.

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

Выбор формата хранения времени в базе данных напрямую влияет на производительность запросов, сложность кода и корректность работы с часовыми поясами. Unix Timestamp — наиболее эффективный формат для реляционных БД: он хранится как целое число (4 или 8 байт), поддерживает индексацию и быструю сортировку. В отличие от строк ISO 8601, timestamp не требует парсинга при сортировке и занимает меньше места в индексе. Для Room и SQLite рекомендуется хранить timestamp в типе INTEGER и использовать индекс на колонке времени.

Формат храненияРазмерСортировкаИндексация
Unix Timestamp (INTEGER)4–8 байтБыстраяЭффективная
ISO 8601 (TEXT)20–30 байтМедленнаяСредняя
DATETIME (SQLite)8 байтСредняяСредняя

Рекомендации для мобильных проектов

Для Android-приложений с Room библиотекой рекомендуется хранить timestamp как Long (64-битный) и использовать TypeConverter для автоматической конвертации между Long и Date или Instant. При запросах к базе используйте операторы сравнения (> , <, BETWEEN) — они работают нативно с целочисленными типами. Для кеширования данных, требующих сортировки по времени (например, список сообщений), обязательно создайте индекс на колонке timestamp — это ускорит запросы с ORDER BY на несколько порядков при большом объёме данных.

Часто задаваемые вопросы

Что такое Unix Timestamp и как он работает?

Unix Timestamp — это количество секунд с 1 января 1970 года 00:00:00 UTC. Он работает как простой счётчик: каждый прошедший день добавляет 86 400 секунд. Это целое число, которое легко сравнивать, сортировать и передавать между сервером и клиентом без привязки к часовому поясу.

Как конвертировать Unix Timestamp в дату на Kotlin?

Используйте Instant.ofEpochSecond(timestamp) для java.time (API 26+) или Date(timestamp * 1000) для старых версий Android. После получения Instant его можно преобразовать в LocalDate, ZonedDateTime или отформатировать через DateTimeFormatter. Не забывайте умножать на 1000, если timestamp в секундах.

В чём суть проблемы 2038 года?

19 января 2038 года в 03:14:07 UTC значение 32-битного signed int (2 147 483 647) будет превышено, что вызовет переполнение. Системы с 32-битным time_t начнут интерпретировать время как отрицательное число. Решение — миграция на 64-битный time_t, который уже используется в современных Android-устройствах (API 21+).

Как получить текущий Unix Timestamp в Android?

Вызовите System.currentTimeMillis() / 1000 для секунд или System.currentTimeMillis() для миллисекунд. Для более точного результата с учётом сетевой синхронизации используйте Instant.now().epochSecond (требуется API 26+) или библиотеки-клиенты NTP для Android.

Чем Unix Timestamp отличается от миллисекунд?

Unix Timestamp — это секунды с 1970-01-01 UTC (integer). Java Timestamp использует миллисекунды — то же смещение, но в 1000 раз точнее. Для конвертации: миллисекунды делятся на 1000. В JSON-API чаще используют секунды (Unix Timestamp), а на платформе Android — миллисекунды (System.currentTimeMillis).

Итоги

  • Unix Timestamp — универсальный целочисленный формат времени, основанный на количестве секунд с 1 января 1970 года UTC
  • Независимость от поясов — timestamp всегда в UTC, преобразование в локальное время выполняется на стороне клиента, что устраняет класс ошибок, связанных с часовыми поясами
  • Конвертация — в Android используется Instant.ofEpochSecond (API 26+) или Date с умножением на 1000 для старых версий платформы
  • Проблема 2038 года — ограничение 32-битного time_t; решение — хранение в 64-битном Long и использование современных версий Android (API 21+)
  • Хранение в БД — timestamp как INTEGER в SQLite/Room эффективнее строк ISO 8601 по размеру, скорости сортировки и индексации
  • Для измерения времени — используйте System.nanoTime() для интервалов, System.currentTimeMillis() для меток времени (с учётом корректировок пользователем)
  • Серверная договорённость — всегда уточняйте единицы измерения (секунды или миллисекунды) в документации API, чтобы избежать ошибок в конвертации

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также