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.ChronoUnitAndroid 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) // falseAdding 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)
)) // 59Measuring 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 minutesFormatting 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| Letter | Meaning | Sample |
|---|---|---|
| yyyy | Year | 2026 |
| MM | Month number | 11 |
| MMM | Month short name | Nov |
| dd | Day of month | 12 |
| HH | Hour, 24-hour clock | 14 |
| hh | Hour, 12-hour clock | 02 |
| mm | Minutes | 05 |
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) // falseTime 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 30mGood Habits
- Store dates in a standard format such as ISO text, and format them only for display.
- Choose
LocalDatefor birthdays andZonedDateTimefor events across regions. - Avoid the old
DateandCalendarclasses in new code.
