Migrate Instant to kotlin.time
This commit is contained in:
parent
79a541b148
commit
6d943c5e1e
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Before kotlin 2.0, there was an excellent library, kotlinx.datetime, which was widely used everywhere, also in Lyng and its dependencies.
|
Before kotlin 2.0, there was an excellent library, kotlinx.datetime, which was widely used everywhere, also in Lyng and its dependencies.
|
||||||
|
|
||||||
When kotlin 2.0 was released, or soon after, JetBrains made an exptic decision to remove `Instant` and `Clock` from kotlinx.datetime and replace it with _yet experimental_ analogs in `kotlin.time`.
|
When Kotlin 2.0 was released, or soon after, JetBrains made a perplexing decision to remove `Instant` and `Clock` from kotlinx.datetime and replace it with _yet experimental_ analogs in `kotlin.time`.
|
||||||
|
|
||||||
The problem is, these were not quite the same (these weren't `@Serializable`!), so people didn't migrate with ease. Okay, then JetBrains decided to not only deprecate it but also make them unusable on Apple targets. It sort of split auditories of many published libraries to those who hate JetBrains and Apple and continue to use 1.9-2.0 compatible versions that no longer work with Kotlin 2.2 on Apple targets (but work pretty well with earlier Kotlin or on other platforms).
|
The problem is, these were not quite the same (these weren't `@Serializable`!), so people didn't migrate with ease. Okay, then JetBrains decided to not only deprecate it but also make them unusable on Apple targets. It sort of split auditories of many published libraries to those who hate JetBrains and Apple and continue to use 1.9-2.0 compatible versions that no longer work with Kotlin 2.2 on Apple targets (but work pretty well with earlier Kotlin or on other platforms).
|
||||||
|
|
||||||
@ -12,14 +12,14 @@ Later JetBrains added serializers for their new `Instant` and `Clock` types, but
|
|||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
We hereby publish a new version of Lyng, 1.0.8-SNAPSHOT, which uses `ktlin.time.Instant` and `kotlin.time.Clock` instead of `kotlinx.datetime.Instant` and `kotlinx.datetime.Clock; it is in other aspects compatible also with Lynon encoded binaries. Still you might need to migrate your code to use `kotlinx.datetime` types.
|
We hereby publish a new version of Lyng, 1.0.8-SNAPSHOT, which uses `kotlin.time.Instant` and `kotlin.time.Clock` instead of `kotlinx.datetime.Instant` and `kotlinx.datetime.Clock`. It is in other aspects compatible also with Lynon encoded binaries. You might need to migrate your code to use `kotlin.time` types. (LocalDateTime/TimeZone still come from `kotlinx.datetime`.)
|
||||||
|
|
||||||
So, if you are getting errors with new version, plase do:
|
So, if you are getting errors with new version, please do:
|
||||||
|
|
||||||
- upgrade to Kotlin 2.2
|
- upgrade to Kotlin 2.2
|
||||||
- upgrade to Lyng 1.0.8-SNAPSHOT
|
- upgrade to Lyng 1.0.8-SNAPSHOT
|
||||||
- replace in your code imports (or other uses) of `kotlinx.datetime.Clock` to `kotlin.time.Clock` and `kotlinx.datetime.Instant` to `kotlin.time.Instant`.
|
- replace in your code imports (or other uses) of `kotlinx.datetime.Clock` to `kotlin.time.Clock` and `kotlinx.datetime.Instant` to `kotlin.time.Instant`.
|
||||||
|
|
||||||
This should solve the problem and hopefully we'll see no more suh a brillant ideas from IDEA ideologspersons.
|
This should solve the problem and hopefully we'll see no more such "brilliant" ideas from IDEA ideologspersons.
|
||||||
|
|
||||||
Sorry for inconvenicence and send a ray of hate to JetBrains ;)
|
Sorry for inconvenience and send a ray of hate to JetBrains ;)
|
||||||
|
|||||||
@ -191,7 +191,7 @@ private suspend fun buildFsModule(module: ModuleScope, policy: FsAccessPolicy) {
|
|||||||
fsGuard {
|
fsGuard {
|
||||||
val self = this.thisObj as ObjPath
|
val self = this.thisObj as ObjPath
|
||||||
val m = self.ensureMetadata()
|
val m = self.ensureMetadata()
|
||||||
m.modifiedAtMillis?.let { ObjInstant(kotlinx.datetime.Instant.fromEpochMilliseconds(it)) } ?: ObjNull
|
m.modifiedAtMillis?.let { ObjInstant(kotlin.time.Instant.fromEpochMilliseconds(it)) } ?: ObjNull
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// modifiedAtMillis(): Int? — milliseconds since epoch or null
|
// modifiedAtMillis(): Int? — milliseconds since epoch or null
|
||||||
|
|||||||
@ -17,7 +17,16 @@
|
|||||||
|
|
||||||
package net.sergeych.lyng.obj
|
package net.sergeych.lyng.obj
|
||||||
|
|
||||||
import kotlinx.datetime.*
|
import kotlinx.datetime.DateTimeUnit
|
||||||
|
import kotlinx.datetime.LocalDateTime
|
||||||
|
import kotlinx.datetime.TimeZone
|
||||||
|
import kotlinx.datetime.UtcOffset
|
||||||
|
import kotlinx.datetime.asTimeZone
|
||||||
|
import kotlinx.datetime.isoDayNumber
|
||||||
|
import kotlinx.datetime.number
|
||||||
|
import kotlinx.datetime.plus
|
||||||
|
import kotlinx.datetime.toInstant
|
||||||
|
import kotlinx.datetime.toLocalDateTime
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import net.sergeych.lyng.Scope
|
import net.sergeych.lyng.Scope
|
||||||
@ -28,12 +37,13 @@ import net.sergeych.lyng.miniast.type
|
|||||||
import net.sergeych.lynon.LynonDecoder
|
import net.sergeych.lynon.LynonDecoder
|
||||||
import net.sergeych.lynon.LynonEncoder
|
import net.sergeych.lynon.LynonEncoder
|
||||||
import net.sergeych.lynon.LynonType
|
import net.sergeych.lynon.LynonType
|
||||||
|
import kotlin.time.Instant
|
||||||
|
|
||||||
class ObjDateTime(val instant: Instant, val timeZone: TimeZone) : Obj() {
|
class ObjDateTime(val instant: Instant, val timeZone: TimeZone) : Obj() {
|
||||||
override val objClass: ObjClass get() = type
|
override val objClass: ObjClass get() = type
|
||||||
|
|
||||||
val localDateTime: LocalDateTime by lazy {
|
val localDateTime: LocalDateTime by lazy {
|
||||||
instant.toLocalDateTime(timeZone)
|
with(timeZone) { instant.toLocalDateTime() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -177,11 +187,11 @@ class ObjDateTime(val instant: Instant, val timeZone: TimeZone) : Obj() {
|
|||||||
addPropertyDoc("year", "The year component.", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("year", "The year component.", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
getter = { thisAs<ObjDateTime>().localDateTime.year.toObj() })
|
getter = { thisAs<ObjDateTime>().localDateTime.year.toObj() })
|
||||||
addPropertyDoc("month", "The month component (1..12).", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("month", "The month component (1..12).", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
getter = { thisAs<ObjDateTime>().localDateTime.monthNumber.toObj() })
|
getter = { thisAs<ObjDateTime>().localDateTime.month.number.toObj() })
|
||||||
addPropertyDoc("dayOfMonth", "The day of month component.", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("dayOfMonth", "The day of month component.", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
getter = { thisAs<ObjDateTime>().localDateTime.dayOfMonth.toObj() })
|
getter = { thisAs<ObjDateTime>().localDateTime.day.toObj() })
|
||||||
addPropertyDoc("day", "Alias to dayOfMonth.", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("day", "Alias to dayOfMonth.", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
getter = { thisAs<ObjDateTime>().localDateTime.dayOfMonth.toObj() })
|
getter = { thisAs<ObjDateTime>().localDateTime.day.toObj() })
|
||||||
addPropertyDoc("hour", "The hour component (0..23).", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("hour", "The hour component (0..23).", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
getter = { thisAs<ObjDateTime>().localDateTime.hour.toObj() })
|
getter = { thisAs<ObjDateTime>().localDateTime.hour.toObj() })
|
||||||
addPropertyDoc("minute", "The minute component (0..59).", type("lyng.Int"), moduleName = "lyng.time",
|
addPropertyDoc("minute", "The minute component (0..59).", type("lyng.Int"), moduleName = "lyng.time",
|
||||||
@ -257,7 +267,7 @@ class ObjDateTime(val instant: Instant, val timeZone: TimeZone) : Obj() {
|
|||||||
returns = type("lyng.DateTime"),
|
returns = type("lyng.DateTime"),
|
||||||
moduleName = "lyng.time") {
|
moduleName = "lyng.time") {
|
||||||
val s = (args.firstAndOnly() as ObjString).value
|
val s = (args.firstAndOnly() as ObjString).value
|
||||||
// kotlinx-datetime's Instant.parse handles RFC3339
|
// kotlin.time's Instant.parse handles RFC3339
|
||||||
// But we want to preserve the offset if present for DateTime.
|
// But we want to preserve the offset if present for DateTime.
|
||||||
// However, Instant.parse("...") always gives an Instant.
|
// However, Instant.parse("...") always gives an Instant.
|
||||||
// If we want the specific offset from the string, we might need a more complex parse.
|
// If we want the specific offset from the string, we might need a more complex parse.
|
||||||
|
|||||||
@ -17,7 +17,13 @@
|
|||||||
|
|
||||||
package net.sergeych.lyng.obj
|
package net.sergeych.lyng.obj
|
||||||
|
|
||||||
import kotlinx.datetime.*
|
import kotlinx.datetime.LocalDateTime
|
||||||
|
import kotlinx.datetime.TimeZone
|
||||||
|
import kotlinx.datetime.UtcOffset
|
||||||
|
import kotlinx.datetime.asTimeZone
|
||||||
|
import kotlinx.datetime.number
|
||||||
|
import kotlinx.datetime.toInstant
|
||||||
|
import kotlinx.datetime.toLocalDateTime
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import net.sergeych.lyng.Scope
|
import net.sergeych.lyng.Scope
|
||||||
@ -27,6 +33,7 @@ import net.sergeych.lynon.LynonEncoder
|
|||||||
import net.sergeych.lynon.LynonSettings
|
import net.sergeych.lynon.LynonSettings
|
||||||
import net.sergeych.lynon.LynonType
|
import net.sergeych.lynon.LynonType
|
||||||
import kotlin.time.Clock
|
import kotlin.time.Clock
|
||||||
|
import kotlin.time.Instant
|
||||||
import kotlin.time.isDistantFuture
|
import kotlin.time.isDistantFuture
|
||||||
import kotlin.time.isDistantPast
|
import kotlin.time.isDistantPast
|
||||||
|
|
||||||
@ -196,8 +203,8 @@ class ObjInstant(val instant: Instant,val truncateMode: LynonSettings.InstantTru
|
|||||||
) {
|
) {
|
||||||
val t = thisAs<ObjInstant>().instant
|
val t = thisAs<ObjInstant>().instant
|
||||||
val tz = TimeZone.UTC
|
val tz = TimeZone.UTC
|
||||||
val dt = t.toLocalDateTime(tz)
|
val dt = with(tz) { t.toLocalDateTime() }
|
||||||
val truncated = LocalDateTime(dt.year, dt.month, dt.dayOfMonth, dt.hour, dt.minute, 0, 0)
|
val truncated = LocalDateTime(dt.year, dt.month.number, dt.day, dt.hour, dt.minute, 0, 0)
|
||||||
ObjInstant(truncated.toInstant(tz), LynonSettings.InstantTruncateMode.Second)
|
ObjInstant(truncated.toInstant(tz), LynonSettings.InstantTruncateMode.Second)
|
||||||
}
|
}
|
||||||
addFnDoc(
|
addFnDoc(
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import net.sergeych.lyng.obj.*
|
|||||||
import net.sergeych.lynon.*
|
import net.sergeych.lynon.*
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.time.Instant
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertContentEquals
|
import kotlin.test.assertContentEquals
|
||||||
@ -368,11 +369,11 @@ class LynonTests {
|
|||||||
roundTrip(ObjReal(1.22345))
|
roundTrip(ObjReal(1.22345))
|
||||||
roundTrip(ObjReal(-Math.PI))
|
roundTrip(ObjReal(-Math.PI))
|
||||||
|
|
||||||
val now = kotlinx.datetime.Instant.fromEpochMilliseconds(System.currentTimeMillis())
|
val now = Instant.fromEpochMilliseconds(System.currentTimeMillis())
|
||||||
roundTrip(ObjInstant(kotlinx.datetime.Instant.fromEpochSeconds(now.epochSeconds), LynonSettings.InstantTruncateMode.Second))
|
roundTrip(ObjInstant(Instant.fromEpochSeconds(now.epochSeconds), LynonSettings.InstantTruncateMode.Second))
|
||||||
roundTrip(
|
roundTrip(
|
||||||
ObjInstant(
|
ObjInstant(
|
||||||
kotlinx.datetime.Instant.fromEpochSeconds(
|
Instant.fromEpochSeconds(
|
||||||
now.epochSeconds,
|
now.epochSeconds,
|
||||||
now.nanosecondsOfSecond / 1_000_000 * 1_000_000
|
now.nanosecondsOfSecond / 1_000_000 * 1_000_000
|
||||||
),
|
),
|
||||||
@ -381,7 +382,7 @@ class LynonTests {
|
|||||||
)
|
)
|
||||||
roundTrip(
|
roundTrip(
|
||||||
ObjInstant(
|
ObjInstant(
|
||||||
kotlinx.datetime.Instant.fromEpochSeconds(
|
Instant.fromEpochSeconds(
|
||||||
now.epochSeconds,
|
now.epochSeconds,
|
||||||
now.nanosecondsOfSecond / 1_000 * 1_000
|
now.nanosecondsOfSecond / 1_000 * 1_000
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user