Avatar ·

Как получить текущий timestamp (метку времени) в Android на Kotlin?

Всем привет! Я начинающий Android-разработчик на Kotlin, и у меня возникла простая, но важная проблема. Мне нужно получить текущий timestamp (метку времени) в моём приложении, чтобы, например, записать его в базу данных или отправить на сервер. Я знаю, что в Java используется System.currentTimeMillis(), но в Kotlin я вижу много разных способов и запутался.

Вот что я пробовал:

val timestamp1 = System.currentTimeMillis()
val timestamp2 = Date().time
val timestamp3 = Calendar.getInstance().timeInMillis

Все эти варианты возвращают какие-то длинные числа. Но я не уверен, какой из них правильный для Android? Есть ли разница между ними? И можно ли как-то получить timestamp в секундах, а не в миллисекундах? Я слышал про Instant.now() из Java 8, но в Android это работает не везде.

Подскажите, пожалуйста, какой способ считается лучшей практикой в 2024 году для Kotlin под Android? Нужно ли подключать какие-то дополнительные библиотеки? Заранее спасибо!

<<>>

Лучший способ получить timestamp в Android на Kotlin

Короткий ответ: используйте System.currentTimeMillis() — это самый быстрый, надёжный и кроссплатформенный способ. Все три ваших варианта возвращают одно и то же значение, просто разными путями. Давайте разберёмся подробнее.

Почему System.currentTimeMillis() — лучший выбор?

  • Скорость: Это нативный вызов, работает за микросекунды.
  • Независимость: Не требует создания объектов (Date, Calendar), не нагружает GC.
  • Точность: Возвращает количество миллисекунд, прошедших с 1 января 1970 года UTC (эпоха Unix).
  • Совместимость: Работает на всех версиях Android без каких-либо дополнительных библиотек.

Правильный код на Kotlin

// Получаем timestamp в миллисекундах (обычный случай)
val timestampMillis: Long = System.currentTimeMillis()
println("Timestamp в миллисекундах: $timestampMillis")

// Если нужен timestamp в секундах (как в Unix-системах)
val timestampSeconds: Long = System.currentTimeMillis() / 1000
println("Timestamp в секундах: $timestampSeconds")

Что насчёт Instant.now() и Java 8 Time API?

Да, Instant.now() — это современный и читаемый способ, но в Android есть нюансы:

  • API 26+ (Android 8.0): Можно использовать напрямую без библиотек.
  • API < 26: Нужно подключить ThreeTenABP — библиотеку, которая "бэкпортит" Java 8 Time API на старые версии.

Пример с Instant (если ваш minSdk >= 26 или вы используете ThreeTenABP):

// Требуется minSdkVersion 26 или библиотека ThreeTenABP
val timestampFromInstant: Long = Instant.now().toEpochMilli()
println("Timestamp через Instant: $timestampFromInstant")

Этот вариант более "котлинистый", но для простого получения timestamp он избыточен. System.currentTimeMillis() делает то же самое без лишних зависимостей.

Сравнение всех способов

СпособПлюсыМинусы
System.currentTimeMillis()Быстро, просто, без GCВозвращает только миллисекунды
Date().timeКороткая записьСоздаёт лишний объект (нагрузка)
Calendar.getInstance()Гибкость (можно менять дату)Медленно, много объектов, не рекомендуется
Instant.now()Современный, читаемыйТребует API 26+ или библиотеку

Важные замечания

1. Timestamp не зависит от часового пояса. Это абсолютное значение. Если вам нужно локальное время (например, "15:30 12.04.2024"), используйте SimpleDateFormat или java.time.

2. Для высокоточных замеров (например, анимации) используйте System.nanoTime(), но он не связан с реальным временем — только для измерения интервалов.

3. В базу данных (Room, SQLite) лучше сохранять Long (миллисекунды) — это универсальный формат.

Итог: Для 99% случаев пишите val now = System.currentTimeMillis(). Это стандарт индустрии, проверенный годами.

<<>>

Альтернативный подход: Kotlin Extensions и timeInMillis

Если вы используете Kotlin и хотите писать более лаконичный код, можно создать extension-функцию для получения timestamp в нужном формате. Это особенно удобно, если вам часто требуется получать метку времени в разных частях приложения.

// Extension-функция для Any? (можно вызывать откуда угодно)
fun Any?.currentTimestampMillis(): Long = System.currentTimeMillis()

// Использование
val timestamp = currentTimestampMillis()
println("Текущий timestamp: $timestamp")

Или, если вы предпочитаете работать с Java 8 Time API и ваш проект уже использует ThreeTenABP (для поддержки старых устройств), можно сделать так:

// Добавьте в build.gradle:
// implementation 'com.jakewharton.threetenabp:threetenabp:1.4.6'
// Инициализация в Application.onCreate():
// AndroidThreeTen.init(this)

// Теперь можно писать:
val timestamp = Instant.now().epochSecond  // в секундах
val timestampMillis = Instant.now().toEpochMilli()  // в миллисекундах

Минус этого подхода: лишняя зависимость, если вам нужно только получать timestamp. Но если вы уже используете LocalDate, ZonedDateTime и другие классы из java.time — библиотека оправдана.

Совет: Не изобретайте велосипед. Если вам не нужны сложные манипуляции с датами — System.currentTimeMillis() остаётся самым простым и эффективным решением. Extension-функции лишь добавляют синтаксический сахар.