Skip to content
AgileLogics
5 min read

Dates and Times

Prerequisites: Classes and objects

On the JVM, dates and times use Java's java.time API, which Kotlin uses directly. (For multiplatform code, the kotlinx-datetime library offers a similar API.)

The main types

Type Represents
LocalDate A calendar date — 2025-01-15
LocalTime A time of day — 09:30
LocalDateTime A date and time, with no time zone
ZonedDateTime A date and time in a specific time zone
Instant An exact moment, in UTC — for timestamps
Duration / Period An amount of time / of calendar days

Example

import java.time.LocalDate
import java.time.Instant
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

fun main() {
    val start = LocalDate.of(2025, 1, 31)
    println(start.plusMonths(1))
    println(start.plusDays(30))
    println(start.dayOfWeek)
    println(ChronoUnit.DAYS.between(start, LocalDate.of(2025, 12, 25)))
    println(start.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")))
    println(LocalDate.parse("2025-03-01").isLeapYear)
    println(Instant.ofEpochSecond(0))
}
2025-02-28
2025-03-02
FRIDAY
328
31/01/2025
false
1970-01-01T00:00:00Z
  • java.time objects are immutable: plusMonths returns a new date.
  • Adding one month to 31 January gives 28 February — calendar rules are handled for you.
  • Instant.ofEpochSecond(0) is the Unix epoch. The Unix Epoch Converter translates timestamps back and forth.

Time zones

Store and compare moments as Instant (UTC), and convert to a user's zone only for display:

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

fun main() {
    val moment = Instant.parse("2025-06-01T12:00:00Z")
    println(moment.atZone(ZoneId.of("Asia/Tokyo")).toLocalTime())
    println(moment.atZone(ZoneId.of("America/New_York")).toLocalTime())
}
21:00
08:00

Common mistakes

  • Using the old java.util.Date and Calendar classes. They're mutable and error-prone; use java.time.
  • Storing local times without a zone, then comparing times from different places.