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

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

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

Начать курс

Введение

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

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

В Kotlin, как и в Java, основная работа с датами и временем строится на пакете java.time. Этот пакет был создан для замены устаревших java.util.Date и java.util.Calendar. Он предлагает неизменяемые (immutable) и потокобезопасные классы. Рассмотрим самые важные из них.

LocalDate — дата без времени

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

import java.time.LocalDate

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

    // Конкретная дата
    val specificDate: LocalDate = LocalDate.of(2025, 12, 25)
    println("Рождество: $specificDate")

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

LocalTime — время без даты

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

import java.time.LocalTime

fun main() {
    val now: LocalTime = LocalTime.now()
    println("Текущее время: $now")

    val meetingTime: LocalTime = LocalTime.of(14, 30)
    println("Встреча в: $meetingTime")

    val oneHourLater: LocalTime = now.plusHours(1)
    println("Через час: $oneHourLater")
}

LocalDateTime — дата и время вместе

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

import java.time.LocalDateTime

fun main() {
    val currentDateTime: LocalDateTime = LocalDateTime.now()
    println("Сейчас: $currentDateTime")

    val newYear: LocalDateTime = LocalDateTime.of(2026, 1, 1, 0, 0)
    println("Новый год: $newYear")
}

ZonedDateTime и Instant — работа с часовыми поясами

ZonedDateTime добавляет к LocalDateTime информацию о часовом поясе (ZoneId). Instant представляет собой момент времени в UTC (машинное время).

import java.time.ZonedDateTime
import java.time.ZoneId
import java.time.Instant

fun main() {
    // Время в конкретном часовом поясе
    val moscowTime: ZonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
    println("Время в Москве: $moscowTime")

    // Текущий момент в UTC
    val instant: Instant = Instant.now()
    println("Метка времени UTC: $instant")
}

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

Для преобразования даты в строку (форматирование) и строки в дату (парсинг) используется класс DateTimeFormatter. Он позволяет задавать любые шаблоны.

Форматирование даты в строку

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

fun main() {
    val date = LocalDate.now()
    val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
    val formattedDate: String = date.format(formatter)
    println("Отформатированная дата: $formattedDate") // Вывод: 11.04.2025

    // Другие примеры шаблонов
    val formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    val dateTime = LocalDateTime.now()
    println(dateTime.format(formatter2))
}

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

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

fun main() {
    val dateString = "25.12.2025"
    val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
    val parsedDate: LocalDate = LocalDate.parse(dateString, formatter)
    println("Распарсеная дата: $parsedDate") // Вывод: 2025-12-25
}

Сравнение и вычисление разницы между датами

Kotlin поддерживает операторы сравнения для дат. Для вычисления разницы используйте классы Duration (для времени) и Period (для дат).

Сравнение дат

import java.time.LocalDate

fun main() {
    val date1 = LocalDate.of(2025, 4, 11)
    val date2 = LocalDate.of(2025, 12, 25)

    println("date1 раньше date2? ${date1.isBefore(date2)}") // true
    println("date1 позже date2? ${date1.isAfter(date2)}")  // false
    println("Даты равны? ${date1.isEqual(date2)}")         // false
}

Разница между датами (Period)

import java.time.LocalDate
import java.time.Period

fun main() {
    val start = LocalDate.of(2025, 1, 1)
    val end = LocalDate.of(2025, 4, 11)

    val period: Period = Period.between(start, end)
    println("Прошло: ${period.years} лет, ${period.months} месяцев, ${period.days} дней")
    // Вывод: Прошло: 0 лет, 3 месяцев, 10 дней
}

Разница во времени (Duration)

import java.time.Duration
import java.time.LocalTime

fun main() {
    val start = LocalTime.of(9, 0)
    val end = LocalTime.of(17, 30)

    val duration: Duration = Duration.between(start, end)
    println("Длительность рабочего дня: ${duration.toHours()} часов ${duration.toMinutes() % 60} минут")
    // Вывод: Длительность рабочего дня: 8 часов 30 минут
}

Практические примеры и лучшие практики

Проверка, является ли год високосным

Блоги

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