diff --git a/docs/migrate_time_to_2_2.md b/docs/migrate_time_to_2_2.md index f429f03..3477c0e 100644 --- a/docs/migrate_time_to_2_2.md +++ b/docs/migrate_time_to_2_2.md @@ -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. -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). @@ -12,14 +12,14 @@ Later JetBrains added serializers for their new `Instant` and `Clock` types, but ## 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 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 ;) \ No newline at end of file +Sorry for inconvenience and send a ray of hate to JetBrains ;) diff --git a/lyngio/src/commonMain/kotlin/net/sergeych/lyng/io/fs/LyngFsModule.kt b/lyngio/src/commonMain/kotlin/net/sergeych/lyng/io/fs/LyngFsModule.kt index ecff150..d65eeee 100644 --- a/lyngio/src/commonMain/kotlin/net/sergeych/lyng/io/fs/LyngFsModule.kt +++ b/lyngio/src/commonMain/kotlin/net/sergeych/lyng/io/fs/LyngFsModule.kt @@ -191,7 +191,7 @@ private suspend fun buildFsModule(module: ModuleScope, policy: FsAccessPolicy) { fsGuard { val self = this.thisObj as ObjPath 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 diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDateTime.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDateTime.kt index dbce33b..ad553b3 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDateTime.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjDateTime.kt @@ -17,7 +17,16 @@ 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.JsonPrimitive import net.sergeych.lyng.Scope @@ -28,12 +37,13 @@ import net.sergeych.lyng.miniast.type import net.sergeych.lynon.LynonDecoder import net.sergeych.lynon.LynonEncoder import net.sergeych.lynon.LynonType +import kotlin.time.Instant class ObjDateTime(val instant: Instant, val timeZone: TimeZone) : Obj() { override val objClass: ObjClass get() = type val localDateTime: LocalDateTime by lazy { - instant.toLocalDateTime(timeZone) + with(timeZone) { instant.toLocalDateTime() } } 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", getter = { thisAs().localDateTime.year.toObj() }) addPropertyDoc("month", "The month component (1..12).", type("lyng.Int"), moduleName = "lyng.time", - getter = { thisAs().localDateTime.monthNumber.toObj() }) + getter = { thisAs().localDateTime.month.number.toObj() }) addPropertyDoc("dayOfMonth", "The day of month component.", type("lyng.Int"), moduleName = "lyng.time", - getter = { thisAs().localDateTime.dayOfMonth.toObj() }) + getter = { thisAs().localDateTime.day.toObj() }) addPropertyDoc("day", "Alias to dayOfMonth.", type("lyng.Int"), moduleName = "lyng.time", - getter = { thisAs().localDateTime.dayOfMonth.toObj() }) + getter = { thisAs().localDateTime.day.toObj() }) addPropertyDoc("hour", "The hour component (0..23).", type("lyng.Int"), moduleName = "lyng.time", getter = { thisAs().localDateTime.hour.toObj() }) 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"), moduleName = "lyng.time") { 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. // However, Instant.parse("...") always gives an Instant. // If we want the specific offset from the string, we might need a more complex parse. diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt index 0e1b33e..b2dcb9a 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt @@ -17,7 +17,13 @@ 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.JsonPrimitive import net.sergeych.lyng.Scope @@ -27,6 +33,7 @@ import net.sergeych.lynon.LynonEncoder import net.sergeych.lynon.LynonSettings import net.sergeych.lynon.LynonType import kotlin.time.Clock +import kotlin.time.Instant import kotlin.time.isDistantFuture import kotlin.time.isDistantPast @@ -196,8 +203,8 @@ class ObjInstant(val instant: Instant,val truncateMode: LynonSettings.InstantTru ) { val t = thisAs().instant val tz = TimeZone.UTC - val dt = t.toLocalDateTime(tz) - val truncated = LocalDateTime(dt.year, dt.month, dt.dayOfMonth, dt.hour, dt.minute, 0, 0) + val dt = with(tz) { t.toLocalDateTime() } + val truncated = LocalDateTime(dt.year, dt.month.number, dt.day, dt.hour, dt.minute, 0, 0) ObjInstant(truncated.toInstant(tz), LynonSettings.InstantTruncateMode.Second) } addFnDoc( diff --git a/lynglib/src/jvmTest/kotlin/LynonTests.kt b/lynglib/src/jvmTest/kotlin/LynonTests.kt index c8197b0..1836559 100644 --- a/lynglib/src/jvmTest/kotlin/LynonTests.kt +++ b/lynglib/src/jvmTest/kotlin/LynonTests.kt @@ -25,6 +25,7 @@ import net.sergeych.lyng.obj.* import net.sergeych.lynon.* import java.nio.file.Files import java.nio.file.Path +import kotlin.time.Instant import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertContentEquals @@ -368,11 +369,11 @@ class LynonTests { roundTrip(ObjReal(1.22345)) roundTrip(ObjReal(-Math.PI)) - val now = kotlinx.datetime.Instant.fromEpochMilliseconds(System.currentTimeMillis()) - roundTrip(ObjInstant(kotlinx.datetime.Instant.fromEpochSeconds(now.epochSeconds), LynonSettings.InstantTruncateMode.Second)) + val now = Instant.fromEpochMilliseconds(System.currentTimeMillis()) + roundTrip(ObjInstant(Instant.fromEpochSeconds(now.epochSeconds), LynonSettings.InstantTruncateMode.Second)) roundTrip( ObjInstant( - kotlinx.datetime.Instant.fromEpochSeconds( + Instant.fromEpochSeconds( now.epochSeconds, now.nanosecondsOfSecond / 1_000_000 * 1_000_000 ), @@ -381,7 +382,7 @@ class LynonTests { ) roundTrip( ObjInstant( - kotlinx.datetime.Instant.fromEpochSeconds( + Instant.fromEpochSeconds( now.epochSeconds, now.nanosecondsOfSecond / 1_000 * 1_000 ),