Skip to content

Commit 19e3160

Browse files
authored
Rework the Windows timezone implementation (#390)
Now, cinterop is not used in timezone implementations, improving compatibility between versions of the library. As part of the rewrite, the allocation strategy on startup was improved, which should lower memory usage during initialization. Additionally, the implementation is now thoroughly tested.
1 parent da6f678 commit 19e3160

File tree

9 files changed

+356
-118
lines changed

9 files changed

+356
-118
lines changed

core/build.gradle.kts

+6-20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import java.io.ByteArrayOutputStream
66
import java.io.PrintWriter
77
import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask
88
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
9+
import org.jetbrains.kotlin.konan.target.Family
910

1011
plugins {
1112
kotlin("multiplatform")
@@ -29,9 +30,6 @@ val serializationVersion: String by project
2930

3031
java {
3132
toolchain { languageVersion.set(JavaLanguageVersion.of(mainJavaToolchainVersion)) }
32-
with(javaToolchains.launcherFor(toolchain).get().metadata) {
33-
logger.info("Using JDK $languageVersion toolchain installed in $installationPath")
34-
}
3533
}
3634

3735
kotlin {
@@ -150,25 +148,13 @@ kotlin {
150148
compilations["test"].kotlinOptions {
151149
freeCompilerArgs += listOf("-trw")
152150
}
153-
when {
154-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.MINGW -> {
155-
compilations["main"].cinterops {
156-
create("declarations") {
157-
defFile("$projectDir/windows/cinterop/definitions.def")
158-
headers("$projectDir/windows/cinterop/definitions.h")
159-
}
151+
if (konanTarget.family == Family.MINGW) {
152+
compilations["test"].cinterops {
153+
create("modern_api") {
154+
defFile("$projectDir/windows/test_cinterop/modern_api.def")
155+
headers("$projectDir/windows/test_cinterop/modern_api.h")
160156
}
161157
}
162-
163-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.LINUX ||
164-
konanTarget.family == org.jetbrains.kotlin.konan.target.Family.ANDROID ||
165-
konanTarget.family.isAppleFamily ->
166-
{
167-
// do nothing special
168-
}
169-
else -> {
170-
throw IllegalArgumentException("Unknown native target ${this@withType}")
171-
}
172158
}
173159
}
174160
sourceSets {

core/native/src/internal/MonthDayTime.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,17 @@ internal class MonthDayTime(
129129
* Converts this [MonthDayTime] to an [Instant] in the given [year],
130130
* using the knowledge of the offset that's in effect at the resulting datetime.
131131
*/
132-
fun toInstant(year: Int, effectiveOffset: UtcOffset): Instant {
133-
val localDateTime = time.resolve(date.toLocalDate(year))
134-
return when (this.offset) {
135-
is OffsetResolver.WallClockOffset -> localDateTime.toInstant(effectiveOffset)
136-
is OffsetResolver.FixedOffset -> localDateTime.toInstant(this.offset.offset)
137-
}
132+
fun toInstant(year: Int, effectiveOffset: UtcOffset): Instant = when (this.offset) {
133+
is OffsetResolver.WallClockOffset -> toLocalDateTime(year).toInstant(effectiveOffset)
134+
is OffsetResolver.FixedOffset -> toLocalDateTime(year).toInstant(this.offset.offset)
138135
}
139136

137+
/**
138+
* Converts this [MonthDayTime] to a [LocalDateTime] in the given [year],
139+
* ignoring the UTC offset.
140+
*/
141+
fun toLocalDateTime(year: Int): LocalDateTime = time.resolve(date.toLocalDate(year))
142+
140143
/**
141144
* Describes how the offset in which the local datetime is expressed is defined.
142145
*/
@@ -160,7 +163,6 @@ internal class MonthDayTime(
160163
* The local time of day at which the transition occurs.
161164
*/
162165
class TransitionLocaltime(val seconds: Int) {
163-
constructor(time: LocalTime) : this(time.toSecondOfDay())
164166

165167
constructor(hour: Int, minute: Int, second: Int) : this(hour * 3600 + minute * 60 + second)
166168

core/native/src/internal/TimeZoneRules.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ internal class RecurringZoneRules(
128128
val offsetBefore: UtcOffset,
129129
val offsetAfter: UtcOffset,
130130
) {
131-
override fun toString(): String = "transitioning to $offsetAfter on $transitionDateTime"
131+
override fun toString(): String = "transitioning from $offsetBefore to $offsetAfter on $transitionDateTime"
132132
}
133133

134134
// see `tzparse` in https://data.iana.org/time-zones/tzdb/localtime.c: looks like there's no guarantees about
135135
// a way to pre-sort the transitions, so we have to do it for each query separately.
136-
private fun rulesForYear(year: Int): List<Rule<Instant>> {
136+
fun rulesForYear(year: Int): List<Rule<Instant>> {
137137
return rules.map { rule ->
138138
val transitionInstant = rule.transitionDateTime.toInstant(year, rule.offsetBefore)
139139
Rule(transitionInstant, rule.offsetBefore, rule.offsetAfter)

core/windows/cinterop/definitions.h

-11
This file was deleted.

0 commit comments

Comments
 (0)