Overview of kotlinx-datetime
masterInstant) and local, time-zone-dependent civil time (e.g., LocalDateTime).repository·master·Indexed 25 days ago
https://github.com/kotlin/kotlinx-datetimeA multiplatform Kotlin library for date and time manipulation providing a pragmatic API based on ISO 8601. It maintains a strict boundary between physical time (Instant) and local civil time (LocalDateTime, LocalDate, LocalTime, YearMonth). The library includes support for time zone conversions, calendar-aware arithmetic, and custom formatting via a Format DSL.
Instant) and local, time-zone-dependent civil time (e.g., LocalDateTime).When dealing with partial data (e.g., just month and day) or invalid/out-of-bounds values (e.g., 23:59:60), use DateTimeComponents. This allows you to parse the data, mutate it to a valid state, and then convert it to a standard type.
// Parsing partial data
val monthDay = DateTimeComponents.Format { monthNumber(); char('/'); day() }
.parse("12/25")
// Handling out-of-bounds seconds
val time = DateTimeComponents.Format { time(LocalTime.Formats.ISO) }
.parse("23:59:60").apply {
if (second == 60) second = 59
}.toLocalTime()
// Formatting complex data
val rfcString = DateTimeComponents.Formats.RFC_1123.format {
setDate(LocalDate(2023, 1, 7))
hour = 23
minute = 59
second = 60
setOffset(UtcOffset(hours = 2))
}Starting with version 0.7.0, kotlinx.datetime.Instant and kotlinx.datetime.Clock have been deprecated in favor of the Kotlin standard library's kotlin.time.Instant and kotlin.time.Clock.
kotlinx-datetime versions, you may encounter ClassNotFoundException. Update those libraries if possible.0.7.1-0.6.x-compat instead of 0.7.1.If you have both import kotlin.time.* and import kotlinx.datetime.*, you may face resolution errors. Explicitly import the specific type you need (e.g., import kotlin.time.Instant).
If you must convert between the two types, use these compatibility functions:
kotlin.time.Instant.toDeprecatedInstant(): kotlinx.datetime.Instantkotlin.time.Clock.toDeprecatedClock(): kotlinx.datetime.Clockkotlinx.datetime.Instant.toStdlibInstant(): kotlin.time.Instantkotlinx.datetime.Clock.toStdlibClock(): kotlin.time.ClockThe library maintains a mapping between IANA timezone names and Windows-specific registry names. If the mapping is outdated, you can update it using a Gradle task.
Steps to update:
master branch../gradlew downloadWindowsZonesMapping.The new mappings were written to the filesystem., verify the changes with git diff.# Update the master branch
git checkout master
git pull
# Run the mapping update task
./gradlew downloadWindowsZonesMapping
# If changes were written, commit them
git checkout -b update-windows-tz-names
git commit -a -m "Update the Windows/IANA timezone name mappings"
git push -u origin update-windows-tz-namesWhen using Maven, you must use the platform-specific -jvm artifact.
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-datetime-jvm</artifactId>
<version>0.8.0</version>
</dependency>To use kotlinx-datetime in your project, ensure mavenCentral() is in your repositories block.
For Multiplatform projects, add the dependency to the commonMain source set.
For Single-platform projects, add it to the standard dependencies block.
// Multiplatform project
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
}
}
}
}
// Single-platform project
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
}Use the following guidance to select the appropriate type for your use case:
| Type | Recommended Use Case |
|---|---|
kotlin.time.Instant | Timestamps of past events (e.g., log entries) or well-defined future events (e.g., a deadline in 1 hour). |
LocalDateTime | Scheduled events in the far future (e.g., a meeting in months) where you must track the TimeZone separately, or for decoding an Instant for UI display. |
LocalDate | Events without a specific time (e.g., a birth date). |
YearMonth | Events without a specific day (e.g., credit card expiration). |
LocalTime | Events without a specific date. |
templatesDir property within the Dokka plugin configuration. This property defines the source directory for your custom templates. For detailed instructions on customizing HTML pages, refer to the official Dokka documentation regarding custom HTML pages.For non-ISO 8601 formats, use the Format DSL. You can define custom patterns or use Unicode-style patterns.
Note: Using non-constant Unicode patterns requires the @OptIn(FormatStringsInDatetimeFormats::class) annotation.
// Custom DSL format
val dateFormat = LocalDate.Format {
monthNumber(padding = Padding.SPACE)
char('/')
day()
char(' ')
year()
}
val date = dateFormat.parse("12/24 2023")
// Unicode pattern with OptIn
@OptIn(FormatStringsInDatetimeFormats::class)
val formatPattern = "yyyy-MM-dd'T'HH:mm:ss[.SSS]"
val dateTimeFormat = LocalDateTime.Format {
byUnicodePattern(formatPattern)
}
val parsed = dateTimeFormat.parse("2023-12-24T23:59:59")By default, Kotlin/Wasm WASI only provides the UTC time zone. To enable all time zones, add the kotlinx-datetime-zoneinfo dependency.
kotlin {
sourceSets {
val wasmWasiMain by getting {
dependencies {
implementation("kotlinx-datetime-zoneinfo", "2026c-spi.0.8.0")
}
}
}
}Wasm/JS follows the same pattern as Kotlin/JS. Add the @js-joda/timezone npm dependency and initialize the module.
// 1. Add npm dependency in Gradle
kotlin {
sourceSets {
val wasmJsMain by getting {
dependencies {
implementation(npm("@js-joda/timezone", "X.X.X"))
}
}
}
}
// 2. Initialize in your code
@JsModule("@js-joda/timezone")
external object JsJodaTimeZoneModule
private val jsJodaTz = JsJodaTimeZoneModuleArithmetic on LocalDateTime is intentionally omitted to prevent errors caused by Daylight Saving Time (DST) transitions (e.g., 'spring forward' gaps).
Best Practice: Perform all arithmetic on Instant values using a TimeZone, then convert the resulting Instant back to LocalDateTime for display.
val timeZone = TimeZone.of("Europe/Berlin")
val localDateTime = LocalDateTime.parse("2021-03-27T02:16:20")
val instant = localDateTime.toInstant(timeZone)
// Perform arithmetic on the Instant
val instantOneDayLater = instant.plus(1, DateTimeUnit.DAY, timeZone)
// Convert back to LocalDateTime
val localDateTimeOneDayLater = instantOneDayLater.toLocalDateTime(timeZone)