Kotlin Date and Time

Apps track birthdays, deadlines, bookings, and reminders. Dates and times look simple, yet they hide many rules about months, leap years, and time zones. Kotlin uses the Java java.time package, which offers clear, safe classes for every need.

A Calendar and a Clock

A wall calendar shows the day. A wall clock shows the hour. A smartwatch shows both together. Three classes match these three tools.

 LocalDate        LocalTime        LocalDateTime
 +---------+      +---------+      +-------------------+
 | NOV     |      |  09:30  |      | NOV 12  +  09:30  |
 |   12    |      |         |      |                   |
 +---------+      +---------+      +-------------------+
 date only        time only        date plus time

Setup

import java.time.*
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

Android projects that support versions below API 26 need core library desugaring to use these classes.

Getting the Current Date and Time

val today = LocalDate.now()
val now = LocalTime.now()
val stamp = LocalDateTime.now()

Creating a Specific Date

val date = LocalDate.of(2026, 11, 12)
val time = LocalTime.of(9, 30)
val both = LocalDateTime.of(2026, 11, 12, 9, 30)

println(date)                 // 2026-11-12
println(date.dayOfWeek)       // THURSDAY
println(date.month)           // NOVEMBER
println(date.isLeapYear)      // false

Adding and Subtracting

These classes are immutable. A call such as plusDays builds a new object and leaves the original untouched.

val start = LocalDate.of(2026, 11, 12)
val later = start.plusDays(30)
val earlier = start.minusMonths(2)

println(later)     // 2026-12-12
println(earlier)   // 2026-09-12
println(start)     // 2026-11-12 (unchanged)

Measuring the Gap

Two tools measure the distance between dates. Period reports years, months, and days. ChronoUnit reports one unit in total.

val from = LocalDate.of(2026, 1, 15)
val to = LocalDate.of(2026, 11, 12)

val gap = Period.between(from, to)
println("${gap.months} months, ${gap.days} days")   // 9 months, 28 days

println(ChronoUnit.DAYS.between(
    LocalDate.of(2026, 1, 1),
    LocalDate.of(2026, 3, 1)
))   // 59

Measuring Clock Time with Duration

val open = LocalTime.of(9, 0)
val close = LocalTime.of(17, 30)
val shift = Duration.between(open, close)
println("${shift.toHours()} hours, ${shift.toMinutesPart()} minutes")  // 8 hours, 30 minutes

Formatting for People

A formatter turns a date object into readable text. Letters in the pattern stand for parts of the date.

val formatter = DateTimeFormatter.ofPattern("dd MMM yyyy")
println(LocalDate.of(2026, 11, 12).format(formatter))   // 12 Nov 2026

val clock = DateTimeFormatter.ofPattern("hh:mm a")
println(LocalTime.of(14, 5).format(clock))              // 02:05 PM
LetterMeaningSample
yyyyYear2026
MMMonth number11
MMMMonth short nameNov
ddDay of month12
HHHour, 24-hour clock14
hhHour, 12-hour clock02
mmMinutes05

Turning Text into a Date

val parsed = LocalDate.parse("2026-11-12")
val custom = LocalDate.parse("12/11/2026", DateTimeFormatter.ofPattern("dd/MM/yyyy"))

Text that does not match the pattern throws a DateTimeParseException. Wrap user input in a try-catch block.

Comparing Dates

val deadline = LocalDate.of(2026, 12, 1)
val today = LocalDate.of(2026, 11, 12)
println(today.isBefore(deadline))   // true
println(today.isAfter(deadline))    // false
println(today == deadline)          // false

Time Zones

A meeting at 9:00 in Delhi happens at a different hour in London. The class ZonedDateTime attaches a zone to the date and time.

val delhi = ZonedDateTime.of(2026, 11, 12, 9, 0, 0, 0, ZoneId.of("Asia/Kolkata"))
val london = delhi.withZoneSameInstant(ZoneId.of("Europe/London"))
println(london.toLocalTime())   // 03:30
 Delhi    09:00  +05:30
   |
   | same moment in time
   v
 London   03:30  +00:00

Kotlin Duration

The Kotlin standard library includes friendly durations.

import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.hours

val total = 2.hours + 30.minutes
println(total)   // 2h 30m

Good Habits

  • Store dates in a standard format such as ISO text, and format them only for display.
  • Choose LocalDate for birthdays and ZonedDateTime for events across regions.
  • Avoid the old Date and Calendar classes in new code.