Работа с датами и временем в Kotlin: от А до Я — полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в работу с датами и временем в Kotlin

Работа с датами и временем — одна из самых частых задач в современной разработке. Будь то логирование событий, расчет сроков, планирование задач или отображение пользовательского интерфейса — без грамотной работы с временными метками не обойтись. В Kotlin, который полностью совместим с Java, стандартом де-факто является пакет java.time, представленный в Java 8. Этот пакет заменил устаревшие java.util.Date и java.util.Calendar, предложив потокобезопасный, иммутабельный и интуитивно понятный API.

В этой статье мы разберем все ключевые аспекты работы с датами и временем в Kotlin: от создания объектов до их форматирования, парсинга и выполнения арифметических операций. Вы узнаете, как использовать LocalDate, LocalTime, LocalDateTime, Instant, Duration и Period на практических примерах.

1. Основные классы для работы с датами и временем

Пакет java.time содержит несколько ключевых классов, каждый из которых решает свою задачу. Рассмотрим их подробнее.

1.1 LocalDate — работа с датой без времени

Класс LocalDate представляет дату (год, месяц, день) без учета времени и часового пояса. Идеально подходит для дней рождения, календарных событий и дат без привязки к конкретному моменту.

import java.time.LocalDate

fun main() {
    // Текущая дата
    val today = LocalDate.now()
    println("Сегодня: $today") // 2025-04-05

    // Конкретная дата
    val newYear = LocalDate.of(2025, 1, 1)
    println("Новый год: $newYear")

    // Парсинг из строки
    val parsedDate = LocalDate.parse("2025-12-31")
    println("Парс даты: $parsedDate")
}

1.2 LocalTime — работа со временем без даты

LocalTime хранит только время (часы, минуты, секунды, наносекунды). Он полезен для хранения времени начала рабочего дня, расписания или таймеров.

import java.time.LocalTime

fun main() {
    // Текущее время
    val now = LocalTime.now()
    println("Сейчас: $now")

    // Конкретное время
    val meetingTime = LocalTime.of(14, 30, 0)
    println("Время встречи: $meetingTime")

    // Парсинг
    val parsedTime = LocalTime.parse("09:15:30")
    println("Парс времени: $parsedTime")
}

1.3 LocalDateTime — объединение даты и времени

LocalDateTime объединяет LocalDate и LocalTime. Это наиболее часто используемый класс для хранения момента времени без часового пояса.

import java.time.LocalDateTime

fun main() {
    // Текущие дата и время
    val current = LocalDateTime.now()
    println("Сейчас: $current")

    // Создание из компонентов
    val specific = LocalDateTime.of(2025, 4, 5, 10, 30, 0)
    println("Конкретный момент: $specific")

    // Комбинация даты и времени
    val date = LocalDate.of(2025, 12, 25)
    val time = LocalTime.of(18, 0)
    val christmas = LocalDateTime.of(date, time)
    println("Рождество: $christmas")
}

1.4 Instant — момент времени в UTC

Instant представляет точку на временной шкале в формате Unix timestamp (количество секунд и наносекунд с 1 января 1970 года). Незаменим для хранения логов, работы с базами данных и обмена данными между системами.

import java.time.Instant

fun main() {
    // Текущий момент в UTC
    val now = Instant.now()
    println("Сейчас (UTC): $now")

    // Из Unix timestamp
    val fromEpoch = Instant.ofEpochSecond(1_700_000_000)
    println("Из timestamp: $fromEpoch")

    // Конвертация в миллисекунды
    val millis = now.toEpochMilli()
    println("Миллисекунды: $millis")
}

2. Форматирование и парсинг дат и времени

Для преобразования дат в строки и обратно используется класс DateTimeFormatter. Он поддерживает как стандартные, так и пользовательские шаблоны.

2.1 Форматирование дат

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

fun main() {
    val now = LocalDateTime.now()

    // Стандартные форматы
    val isoFormat = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    println("ISO: $isoFormat")

    // Пользовательский формат
    val customFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")
    val formatted = now.format(customFormatter)
    println("Формат: $formatted")

    // Другой пример
    val dateFormatter = DateTimeFormatter.ofPattern("EEEE, MMMM d, yyyy")
    println("Читаемый: ${now.format(dateFormatter)}")
}

2.2 Парсинг строк в даты

import java.time.LocalDate
import java.time.format.DateTimeFormatter

fun main() {
    val dateString = "05.04.2025"
    val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
    val date = LocalDate.parse(dateString, formatter)
    println("Распарсено: $date")

    // Обработка ошибок
    try {
        val badDate = LocalDate.parse("2025/04/05")
    } catch (e: Exception) {
        println("Ошибка парсинга: ${e.message}")
    }
}

3. Манипуляции с датами и временем

Kotlin позволяет легко прибавлять и вычитать дни, месяцы, годы, а также находить разницу между датами.

3.1 Прибавление и вычитание

import java.time.LocalDate
import java.time.LocalDateTime

fun main() {
    val today = LocalDate.now()

    // Прибавление дней
    val nextWeek = today.plusDays(7)
    println("Через неделю: $nextWeek")

    // Вычитание месяцев
    val twoMonthsAgo = today.minusMonths(2)
    println("2 месяца назад: $twoMonthsAgo")

    // Работа с LocalDateTime
    val now = LocalDateTime.now()
    val nextHour = now.plusHours(1).plusMinutes(30)
    println("Через 1.5 часа: $nextHour")
}

3.2 Разница между датами

Для измерения разницы во времени используются класс

Блоги

Рекомендаций по книгам