Introduction to Working with Dates and Time in Kotlin
Working with dates and time is one of the most common tasks in modern development. Whether it's event logging, calculating deadlines, task scheduling, or displaying a user interface — proper handling of timestamps is essential. In Kotlin, which is fully compatible with Java, the de facto standard is the java.time package, introduced in Java 8. This package replaced the outdated java.util.Date and java.util.Calendar, offering a thread-safe, immutable, and intuitive API.
In this article, we will cover all key aspects of working with dates and time in Kotlin: from creating objects to formatting, parsing, and performing arithmetic operations. You will learn how to use LocalDate, LocalTime, LocalDateTime, Instant, Duration, and Period with practical examples.
1. Main Classes for Working with Dates and Time
The java.time package contains several key classes, each solving a specific task. Let's look at them in detail.
1.1 LocalDate — Working with Date Without Time
The LocalDate class represents a date (year, month, day) without time and time zone. It is ideal for birthdays, calendar events, and dates not tied to a specific moment.
import java.time.LocalDate
fun main() { // Current date val today = LocalDate.now() println("Today: $today") // 2025-04-05
// Specific date val newYear = LocalDate.of(2025, 1, 1) println("New Year: $newYear")
// Parsing from string val parsedDate = LocalDate.parse("2025-12-31") println("Parsed date: $parsedDate")}1.2 LocalTime — Working with Time Without Date
LocalTime stores only time (hours, minutes, seconds, nanoseconds). It is useful for storing the start time of a workday, schedules, or timers.
import java.time.LocalTime
fun main() { // Current time val now = LocalTime.now() println("Now: $now")
// Specific time val meetingTime = LocalTime.of(14, 30, 0) println("Meeting time: $meetingTime")
// Parsing val parsedTime = LocalTime.parse("09:15:30") println("Parsed time: $parsedTime")}1.3 LocalDateTime — Combining Date and Time
LocalDateTime combines LocalDate and LocalTime. This is the most commonly used class for storing a point in time without a time zone.
import java.time.LocalDateTime
fun main() { // Current date and time val current = LocalDateTime.now() println("Now: $current")
// Creating from components val specific = LocalDateTime.of(2025, 4, 5, 10, 30, 0) println("Specific moment: $specific")
// Combining date and time val date = LocalDate.of(2025, 12, 25) val time = LocalTime.of(18, 0) val christmas = LocalDateTime.of(date, time) println("Christmas: $christmas")}1.4 Instant — Point in Time in UTC
Instant represents a point on the timeline in Unix timestamp format (number of seconds and nanoseconds since January 1, 1970). It is indispensable for storing logs, working with databases, and exchanging data between systems.
import java.time.Instant
fun main() { // Current moment in UTC val now = Instant.now() println("Now (UTC): $now")
// From Unix timestamp val fromEpoch = Instant.ofEpochSecond(1_700_000_000) println("From timestamp: $fromEpoch")
// Conversion to milliseconds val millis = now.toEpochMilli() println("Milliseconds: $millis")}2. Formatting and Parsing Dates and Time
To convert dates to strings