How to Work with Dates and Time in Kotlin with the Java Time API
Working with dates and time can quickly become a headache in any programming language. Fortunately, Kotlin leverages the robust Java Time API introduced in Java 8, which offers a clean, immutable, and powerful approach to date and time manipulation. Whether you’re building scheduling features, formatting timestamps, or performing date arithmetic, the Java Time API gives you all the tools you need.
🕒 Getting Started with java.time
The java.time package offers several key classes:
LocalDate– A date without time (e.g., 2025-06-04)LocalTime– A time without date (e.g., 14:35:20)LocalDateTime– Date and time without a timezoneZonedDateTime– Date and time with a timezoneInstant– A point on the timeline (in UTC)
These classes are immutable and thread-safe, making them perfect for multi-threaded applications.
📅 Creating Date and Time Instances
Using now():
import java.time.*val currentDate = LocalDate.now()
val currentTime = LocalTime.now()
val currentDateTime = LocalDateTime.now()
val currentInstant = Instant.now()println("Date: $currentDate")
println("Time: $currentTime")
println("DateTime: $currentDateTime")
println("Instant: $currentInstant")
Using of():
val customDate = LocalDate.of(2025, Month.JUNE, 4)
val customTime = LocalTime.of(14, 30)
val customDateTime = LocalDateTime.of(customDate, customTime)🛠 Manipulating Dates and Time
You can easily perform operations like adding or subtracting days, months, or years.
val nextWeek = currentDate.plusWeeks(1)
val lastMonth = currentDate.minusMonths(1)
val tomorrow = currentDate.plusDays(1)Want to know the day of the week?
val dayOfWeek = currentDate.dayOfWeek
println("Today is: $dayOfWeek")🕹 Formatting and Parsing
Formatting and parsing are done using DateTimeFormatter.
Formatting:
import java.time.format.DateTimeFormatterval formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm")
val formatted = currentDateTime.format(formatter)println("Formatted datetime: $formatted")
Parsing:
val dateString = "04-06-2025 14:30"
val parsedDateTime = LocalDateTime.parse(dateString, formatter)
println("Parsed datetime: $parsedDateTime")🌍 Working with Time Zones
If you’re dealing with global users, use ZonedDateTime.
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"))
println("Tokyo time: $zonedDateTime")val utc = ZonedDateTime.now(ZoneOffset.UTC)
println("UTC time: $utc")Convert between zones:
val newYorkTime = zonedDateTime.withZoneSameInstant(ZoneId.of("America/New_York"))
println("New York time: $newYorkTime")⏳ Calculating Duration and Period
Duration – for time-based differences (hours, minutes, seconds):
val startTime = LocalTime.of(9, 0)
val endTime = LocalTime.of(17, 30)val duration = Duration.between(startTime, endTime)
println("Duration in hours: ${duration.toHours()}")Period – for date-based differences (days, months, years):
val startDate = LocalDate.of(2020, 1, 1)
val endDate = LocalDate.of(2025, 6, 4)val period = Period.between(startDate, endDate)
println("Period: ${period.years} years, ${period.months} months, ${period.days} days")🔁 Convert Between Legacy Date and Java Time
Need to work with legacy java.util.Date?
import java.util.Date
import java.time.ZoneIdval date = Date()
val instantFromDate = date.toInstant()
val localDateTime = LocalDateTime.ofInstant(instantFromDate, ZoneId.systemDefault())// Reverse
val dateFromInstant = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant())
Final Thoughts
Kotlin’s seamless interop with the Java Time API makes working with date and time intuitive, safe, and powerful. You avoid mutable classes like Calendar and the error-prone Date class while benefiting from immutability and clear APIs.
Get REIT monero’s stories in your inbox
Join Medium for free to get updates from this writer.
Pro Tip: Always prefer ZonedDateTime or Instant when storing dates that will be used across different time zones. It helps prevent many localization and daylight saving bugs.




