A multiplatform Kotlin library for working with date and time with JVM target support.
—
This document covers the bidirectional converter functions for seamless integration with existing Java codebases using java.time types. All converters provide zero-overhead conversion between kotlinx-datetime and java.time.
kotlinx-datetime provides extension functions for converting between kotlinx-datetime types and their corresponding java.time equivalents. This enables:
Convert between kotlinx.datetime.LocalDate and java.time.LocalDate.
// kotlinx-datetime to java.time
fun LocalDate.toJavaLocalDate(): java.time.LocalDate
// java.time to kotlinx-datetime
fun java.time.LocalDate.toKotlinLocalDate(): LocalDateimport kotlinx.datetime.LocalDate
import kotlinx.datetime.toJavaLocalDate
import kotlinx.datetime.toKotlinLocalDate
// Convert kotlinx-datetime to java.time
val kotlinxDate = LocalDate(2023, 12, 25)
val javaDate = kotlinxDate.toJavaLocalDate()
// Use with java.time APIs
val daysInMonth = javaDate.lengthOfMonth()
val isLeapYear = javaDate.isLeapYear
// Convert java.time to kotlinx-datetime
val javaDateFromDb = java.time.LocalDate.of(2023, 6, 15)
val kotlinxDate2 = javaDateFromDb.toKotlinLocalDate()
// Interoperability with existing APIs
fun processJavaDate(date: java.time.LocalDate) {
val kotlinxDate = date.toKotlinLocalDate()
// Use kotlinx-datetime operations
val futureDate = kotlinxDate.plus(30, DateTimeUnit.DAY)
println("30 days later: ${futureDate.toJavaLocalDate()}")
}Convert between kotlinx.datetime.LocalTime and java.time.LocalTime.
// kotlinx-datetime to java.time
fun LocalTime.toJavaLocalTime(): java.time.LocalTime
// java.time to kotlinx-datetime
fun java.time.LocalTime.toKotlinLocalTime(): LocalTimeimport kotlinx.datetime.LocalTime
import kotlinx.datetime.toJavaLocalTime
import kotlinx.datetime.toKotlinLocalTime
// Convert kotlinx-datetime to java.time
val kotlinxTime = LocalTime(14, 30, 45, 123_456_789)
val javaTime = kotlinxTime.toJavaLocalTime()
// Use with java.time APIs
val hourOfDay = javaTime.hour
val truncatedToMinutes = javaTime.truncatedTo(java.time.temporal.ChronoUnit.MINUTES)
// Convert java.time to kotlinx-datetime
val javaTimeFromSystem = java.time.LocalTime.now()
val kotlinxTime2 = javaTimeFromSystem.toKotlinLocalTime()
// Database integration example
fun saveTimeToDatabase(time: LocalTime) {
val javaTime = time.toJavaLocalTime()
// Use with JPA/Hibernate that expects java.time.LocalTime
entityManager.persist(TimeEntity(scheduledAt = javaTime))
}Convert between kotlinx.datetime.LocalDateTime and java.time.LocalDateTime.
// kotlinx-datetime to java.time
fun LocalDateTime.toJavaLocalDateTime(): java.time.LocalDateTime
// java.time to kotlinx-datetime
fun java.time.LocalDateTime.toKotlinLocalDateTime(): LocalDateTimeimport kotlinx.datetime.LocalDateTime
import kotlinx.datetime.toJavaLocalDateTime
import kotlinx.datetime.toKotlinLocalDateTime
// Convert kotlinx-datetime to java.time
val kotlinxDateTime = LocalDateTime(2023, 12, 25, 14, 30, 45)
val javaDateTime = kotlinxDateTime.toJavaLocalDateTime()
// Use with java.time APIs
val year = javaDateTime.year
val withNano = javaDateTime.withNano(123_456_789)
// Convert java.time to kotlinx-datetime
val javaDateTimeFromApi = java.time.LocalDateTime.parse("2023-12-25T14:30:45")
val kotlinxDateTime2 = javaDateTimeFromApi.toKotlinLocalDateTime()
// API integration example
fun handleApiResponse(javaDateTime: java.time.LocalDateTime) {
val kotlinxDateTime = javaDateTime.toKotlinLocalDateTime()
val timeZone = TimeZone.currentSystemDefault()
val instant = kotlinxDateTime.toInstant(timeZone)
println("Instant: $instant")
}Convert between kotlin.time.Instant and java.time.Instant.
// kotlin.time to java.time
fun Instant.toJavaInstant(): java.time.Instant
// java.time to kotlin.time
fun java.time.Instant.toKotlinInstant(): Instantimport kotlin.time.Instant
import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toKotlinInstant
import kotlinx.datetime.Clock
// Convert kotlin.time to java.time
val kotlinInstant = Clock.System.now()
val javaInstant = kotlinInstant.toJavaInstant()
// Use with java.time APIs
val epochMilli = javaInstant.toEpochMilli()
val plusSeconds = javaInstant.plusSeconds(3600)
// Convert java.time to kotlin.time
val javaInstantFromSystem = java.time.Instant.now()
val kotlinInstant2 = javaInstantFromSystem.toKotlinInstant()
// Database timestamp example
fun logEvent(event: String) {
val instant = Clock.System.now()
val javaInstant = instant.toJavaInstant()
// Use with database APIs expecting java.time.Instant
val timestamp = java.sql.Timestamp.from(javaInstant)
logRepository.save(LogEntry(event, timestamp))
}Convert between kotlinx.datetime.TimeZone and java.time.ZoneId.
// kotlinx-datetime to java.time
fun TimeZone.toJavaZoneId(): java.time.ZoneId
// java.time to kotlinx-datetime
fun java.time.ZoneId.toKotlinTimeZone(): TimeZoneimport kotlinx.datetime.TimeZone
import kotlinx.datetime.toJavaZoneId
import kotlinx.datetime.toKotlinTimeZone
// Convert kotlinx-datetime to java.time
val kotlinxTimeZone = TimeZone.of("America/New_York")
val javaZoneId = kotlinxTimeZone.toJavaZoneId()
// Use with java.time APIs
val zoneRules = javaZoneId.rules
val displayName = javaZoneId.getDisplayName(
java.time.format.TextStyle.FULL,
java.util.Locale.US
)
// Convert java.time to kotlinx-datetime
val javaZoneFromSystem = java.time.ZoneId.systemDefault()
val kotlinxTimeZone2 = javaZoneFromSystem.toKotlinTimeZone()
// Scheduling system integration
fun scheduleTask(dateTime: LocalDateTime, timeZone: TimeZone) {
val javaDateTime = dateTime.toJavaLocalDateTime()
val javaZone = timeZone.toJavaZoneId()
val zonedDateTime = java.time.ZonedDateTime.of(javaDateTime, javaZone)
// Use with scheduling library expecting java.time types
scheduler.schedule(task, zonedDateTime)
}Convert between kotlinx.datetime.UtcOffset and java.time.ZoneOffset.
// kotlinx-datetime to java.time
fun UtcOffset.toJavaZoneOffset(): java.time.ZoneOffset
// java.time to kotlinx-datetime
fun java.time.ZoneOffset.toKotlinUtcOffset(): UtcOffsetimport kotlinx.datetime.UtcOffset
import kotlinx.datetime.toJavaZoneOffset
import kotlinx.datetime.toKotlinUtcOffset
// Convert kotlinx-datetime to java.time
val kotlinxOffset = UtcOffset(hours = -5, minutes = 30)
val javaOffset = kotlinxOffset.toJavaZoneOffset()
// Use with java.time APIs
val totalSeconds = javaOffset.totalSeconds
val offsetTime = java.time.OffsetTime.of(14, 30, 0, 0, javaOffset)
// Convert java.time to kotlinx-datetime
val javaOffsetFromApi = java.time.ZoneOffset.ofHours(2)
val kotlinxOffset2 = javaOffsetFromApi.toKotlinUtcOffset()Convert between kotlinx.datetime.Month and java.time.Month.
// kotlinx-datetime to java.time
fun Month.toJavaMonth(): java.time.Month
// java.time to kotlinx-datetime
fun java.time.Month.toKotlinMonth(): Monthimport kotlinx.datetime.Month
import kotlinx.datetime.toJavaMonth
import kotlinx.datetime.toKotlinMonth
// Convert kotlinx-datetime to java.time
val kotlinxMonth = Month.DECEMBER
val javaMonth = kotlinxMonth.toJavaMonth()
// Use with java.time APIs
val monthValue = javaMonth.value // 12
val displayName = javaMonth.getDisplayName(
java.time.format.TextStyle.FULL,
java.util.Locale.US
) // "December"
// Convert java.time to kotlinx-datetime
val javaMonthFromApi = java.time.Month.JUNE
val kotlinxMonth2 = javaMonthFromApi.toKotlinMonth()
// Business logic example
fun getSeasonForMonth(month: Month): String {
val javaMonth = month.toJavaMonth()
return when (javaMonth) {
java.time.Month.DECEMBER, java.time.Month.JANUARY, java.time.Month.FEBRUARY -> "Winter"
java.time.Month.MARCH, java.time.Month.APRIL, java.time.Month.MAY -> "Spring"
java.time.Month.JUNE, java.time.Month.JULY, java.time.Month.AUGUST -> "Summer"
else -> "Fall"
}
}Convert between kotlinx.datetime.YearMonth and java.time.YearMonth.
// kotlinx-datetime to java.time
fun YearMonth.toJavaYearMonth(): java.time.YearMonth
// java.time to kotlinx-datetime
fun java.time.YearMonth.toKotlinYearMonth(): YearMonthimport kotlinx.datetime.YearMonth
import kotlinx.datetime.toJavaYearMonth
import kotlinx.datetime.toKotlinYearMonth
// Convert kotlinx-datetime to java.time
val kotlinxYearMonth = YearMonth(2023, 12)
val javaYearMonth = kotlinxYearMonth.toJavaYearMonth()
// Use with java.time APIs
val lengthOfMonth = javaYearMonth.lengthOfMonth() // 31
val isLeapYear = javaYearMonth.isLeapYear
// Convert java.time to kotlinx-datetime
val javaYearMonthFromDb = java.time.YearMonth.of(2023, 6)
val kotlinxYearMonth2 = javaYearMonthFromDb.toKotlinYearMonth()
// Reporting system example
fun generateMonthlyReport(yearMonth: YearMonth): Report {
val javaYearMonth = yearMonth.toJavaYearMonth()
val startOfMonth = javaYearMonth.atDay(1)
val endOfMonth = javaYearMonth.atEndOfMonth()
return Report(
period = yearMonth,
startDate = startOfMonth.toKotlinLocalDate(),
endDate = endOfMonth.toKotlinLocalDate()
)
}Convert between kotlinx.datetime.DayOfWeek and java.time.DayOfWeek.
// kotlinx-datetime to java.time
fun DayOfWeek.toJavaDayOfWeek(): java.time.DayOfWeek
// java.time to kotlinx-datetime
fun java.time.DayOfWeek.toKotlinDayOfWeek(): DayOfWeekimport kotlinx.datetime.DayOfWeek
import kotlinx.datetime.toJavaDayOfWeek
import kotlinx.datetime.toKotlinDayOfWeek
// Convert kotlinx-datetime to java.time
val kotlinxDayOfWeek = DayOfWeek.FRIDAY
val javaDayOfWeek = kotlinxDayOfWeek.toJavaDayOfWeek()
// Use with java.time APIs
val dayValue = javaDayOfWeek.value // 5
val displayName = javaDayOfWeek.getDisplayName(
java.time.format.TextStyle.FULL,
java.util.Locale.US
) // "Friday"
// Convert java.time to kotlinx-datetime
val javaDayFromTemporal = java.time.LocalDate.now().dayOfWeek
val kotlinxDayOfWeek2 = javaDayFromTemporal.toKotlinDayOfWeek()
// Business hours calculation example
fun isBusinessDay(dayOfWeek: DayOfWeek): Boolean {
val javaDayOfWeek = dayOfWeek.toJavaDayOfWeek()
return javaDayOfWeek != java.time.DayOfWeek.SATURDAY &&
javaDayOfWeek != java.time.DayOfWeek.SUNDAY
}Convert between kotlin.time.Duration and java.time.Duration.
// kotlin.time to java.time
fun Duration.toJavaDuration(): java.time.Duration
// java.time to kotlin.time
fun java.time.Duration.toKotlinDuration(): Durationimport kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
import kotlinx.datetime.toJavaDuration
import kotlinx.datetime.toKotlinDuration
// Convert kotlin.time to java.time
val kotlinDuration = 2.hours + 30.minutes
val javaDuration = kotlinDuration.toJavaDuration()
// Use with java.time APIs
val seconds = javaDuration.seconds
val nanos = javaDuration.nano
// Convert java.time to kotlin.time
val javaDurationFromApi = java.time.Duration.ofHours(8)
val kotlinDuration2 = javaDurationFromApi.toKotlinDuration()
// Task scheduling example
fun schedulePeriodicTask(interval: Duration) {
val javaDuration = interval.toJavaDuration()
// Use with Java scheduling APIs
scheduledExecutor.scheduleAtFixedRate(
task,
0,
javaDuration.toMillis(),
java.util.concurrent.TimeUnit.MILLISECONDS
)
}// JPA Entity with java.time types
@Entity
data class EventEntity(
@Id val id: String,
val title: String,
val startTime: java.time.Instant,
val date: java.time.LocalDate,
val timeZone: String
)
// Service layer with kotlinx-datetime
class EventService {
fun createEvent(title: String, dateTime: LocalDateTime, timeZone: TimeZone): String {
val instant = dateTime.toInstant(timeZone)
val entity = EventEntity(
id = UUID.randomUUID().toString(),
title = title,
startTime = instant.toJavaInstant(), // Convert for database
date = dateTime.date.toJavaLocalDate(), // Convert for database
timeZone = timeZone.id
)
return repository.save(entity).id
}
fun getEvent(id: String): Event? {
val entity = repository.findById(id) ?: return null
return Event(
id = entity.id,
title = entity.title,
instant = entity.startTime.toKotlinInstant(), // Convert from database
date = entity.date.toKotlinLocalDate(), // Convert from database
timeZone = TimeZone.of(entity.timeZone)
)
}
}// External API client expecting java.time types
class ExternalCalendarClient {
fun scheduleEvent(
title: String,
startTime: java.time.ZonedDateTime,
duration: java.time.Duration
): CompletableFuture<String>
}
// Internal service using kotlinx-datetime
class CalendarService(private val client: ExternalCalendarClient) {
suspend fun scheduleEvent(
title: String,
dateTime: LocalDateTime,
timeZone: TimeZone,
duration: DateTimePeriod
): String {
// Convert kotlinx-datetime types to java.time for external API
val javaDateTime = dateTime.toJavaLocalDateTime()
val javaZoneId = timeZone.toJavaZoneId()
val zonedDateTime = java.time.ZonedDateTime.of(javaDateTime, javaZoneId)
// Convert period to duration (simplified for time-based components)
val javaDuration = java.time.Duration.ofHours(duration.hours.toLong())
.plusMinutes(duration.minutes.toLong())
.plusSeconds(duration.seconds.toLong())
return client.scheduleEvent(title, zonedDateTime, javaDuration).await()
}
}// Legacy code using java.time
class LegacyDateUtils {
companion object {
@JvmStatic
fun addBusinessDays(date: java.time.LocalDate, days: Int): java.time.LocalDate {
// Existing java.time-based logic
var result = date
var addedDays = 0
while (addedDays < days) {
result = result.plusDays(1)
if (result.dayOfWeek != java.time.DayOfWeek.SATURDAY &&
result.dayOfWeek != java.time.DayOfWeek.SUNDAY) {
addedDays++
}
}
return result
}
}
}
// New code using kotlinx-datetime with legacy integration
class ModernDateService {
fun addBusinessDays(date: LocalDate, days: Int): LocalDate {
val javaDate = date.toJavaLocalDate()
val resultJavaDate = LegacyDateUtils.addBusinessDays(javaDate, days)
return resultJavaDate.toKotlinLocalDate()
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlinx--kotlinx-datetime-jvm