Skip to content

Commit

Permalink
Use the correct tzdb path on the iOS Simulator devices
Browse files Browse the repository at this point in the history
  • Loading branch information
dkhalanskyjb committed Dec 11, 2023
1 parent 1881392 commit 6448e6f
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 54 deletions.
45 changes: 23 additions & 22 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,28 @@ kotlin {
target("androidNativeX64")
*/
common("darwin") {
// Tier 1
target("macosX64")
target("macosArm64")
target("iosSimulatorArm64")
target("iosX64")
// Tier 2
target("watchosSimulatorArm64")
target("watchosX64")
target("watchosArm32")
target("watchosArm64")
target("tvosSimulatorArm64")
target("tvosX64")
target("tvosArm64")
target("iosArm64")
// Tier 3
target("watchosDeviceArm64")
common("darwinDevices") {
// Tier 1
target("macosX64")
target("macosArm64")
// Tier 2
target("watchosX64")
target("watchosArm32")
target("watchosArm64")
target("tvosX64")
target("tvosArm64")
target("iosArm64")
// Tier 3
target("watchosDeviceArm64")
}
common("darwinSimulator") {
// Tier 1
target("iosSimulatorArm64")
target("iosX64")
// Tier 2
target("watchosSimulatorArm64")
target("tvosSimulatorArm64")
}
}
}
// Tier 3
Expand Down Expand Up @@ -155,12 +161,7 @@ kotlin {
// do nothing special
}
konanTarget.family.isAppleFamily -> {
compilations["main"].cinterops {
create("declarations") {
defFile("$projectDir/darwin/cinterop/definitions.def")
headers("$projectDir/darwin/cinterop/definitions.h")
}
}
// do nothing special
}
else -> {
throw IllegalArgumentException("Unknown native target ${this@withType}")
Expand Down
1 change: 0 additions & 1 deletion core/darwin/cinterop/definitions.def

This file was deleted.

9 changes: 0 additions & 9 deletions core/darwin/cinterop/definitions.h

This file was deleted.

2 changes: 2 additions & 0 deletions core/darwin/src/Converters.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public fun NSDate.toKotlinInstant(): Instant {
* to [TimeZone.offset]) and the offset is not given in even minutes but also includes seconds, this method throws
* [IllegalArgumentException] to denote that lossy conversion would happen, as Darwin internally rounds the offsets to the
* nearest minute.
*
* If the time zone is unknown to the Foundation framework, [IllegalArgumentException] will be thrown.
*/
public fun TimeZone.toNSTimeZone(): NSTimeZone = if (this is FixedOffsetTimeZone) {
require (offset.totalSeconds % 60 == 0) {
Expand Down
5 changes: 0 additions & 5 deletions core/darwin/src/TimeZoneNative.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@

package kotlinx.datetime

import kotlinx.datetime.internal.*
import platform.Foundation.*

// iOS simulator needs a different path, hence the check. See https://github.com/HowardHinnant/date/pull/577
internal actual val systemTzdb: TimezoneDatabase = TzdbOnFilesystem(Path.fromString(
if (kotlinxDatetimeRunningInSimulator) "/usr/share/zoneinfo" else "/var/db/timezone/zoneinfo"))

internal actual fun currentSystemDefaultZone(): RegionTimeZone {
/* The framework has its own cache of the system timezone. Calls to
[NSTimeZone systemTimeZone] do not reflect changes to the system timezone
Expand Down
1 change: 0 additions & 1 deletion core/darwin/test/ConvertersTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class ConvertersTest {
if (timeZone is FixedOffsetTimeZone) {
continue
}
// TODO: investigate failure
val nsTimeZone = try { timeZone.toNSTimeZone() } catch (e: IllegalArgumentException) { continue }
assertEquals(normalizedId, nsTimeZone.name)
assertEquals(timeZone, nsTimeZone.toKotlinTimeZone())
Expand Down
10 changes: 10 additions & 0 deletions core/darwinDevices/src/TimeZoneNative.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2019-2023 JetBrains s.r.o. and contributors.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package kotlinx.datetime

import kotlinx.datetime.internal.*

internal actual fun getTzdbPath(): Path = Path.fromString("/var/db/timezone/zoneinfo")
10 changes: 10 additions & 0 deletions core/darwinSimulator/src/TimeZoneNative.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2019-2023 JetBrains s.r.o. and contributors.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package kotlinx.datetime

import kotlinx.datetime.internal.*

internal actual fun getTzdbPath(): Path = Path.fromString("/usr/share/zoneinfo.default")
18 changes: 16 additions & 2 deletions core/linux/src/TimeZoneNative.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ package kotlinx.datetime

import kotlinx.datetime.internal.*

internal actual val systemTzdb: TimezoneDatabase = TzdbOnFilesystem(Path.fromString("/usr/share/zoneinfo"))

internal actual fun currentSystemDefaultZone(): RegionTimeZone {
val zoneId = pathToSystemDefault()?.second?.toString()
?: throw IllegalStateException("Failed to get the system timezone")
return RegionTimeZone(systemTzdb.rulesForId(zoneId), zoneId)
}

internal actual fun getTzdbPath(): Path {
val defaultPath = Path.fromString("/usr/share/zoneinfo")
return defaultPath.check()?.let { defaultPath }
?: pathToSystemDefault()?.first ?: throw IllegalStateException("Could not find the path to the timezone database")
}

private fun pathToSystemDefault(): Pair<Path, Path>? {
val info = Path(true, listOf("etc", "localtime")).readLink() ?: return null
val i = info.components.indexOf("zoneinfo")
if (!info.isAbsolute || i == -1 || i == info.components.size - 1) return null
return Pair(
Path(true, info.components.subList(0, i + 1)),
Path(false, info.components.subList(i + 1, info.components.size))
)
}
12 changes: 12 additions & 0 deletions core/nix/src/TimeZoneNative.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright 2019-2023 JetBrains s.r.o. and contributors.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/

package kotlinx.datetime

import kotlinx.datetime.internal.*

internal expect fun getTzdbPath(): Path

internal actual val systemTzdb: TimezoneDatabase = TzdbOnFilesystem(getTzdbPath())
15 changes: 1 addition & 14 deletions core/nix/src/internal/TzdbOnFilesystem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package kotlinx.datetime.internal

import kotlinx.datetime.*

internal class TzdbOnFilesystem(defaultTzdbPath: Path): TimezoneDatabase {
internal class TzdbOnFilesystem(val tzdbPath: Path): TimezoneDatabase {

override fun rulesForId(id: String): TimeZoneRules =
readTzFile(tzdbPath.resolve(Path.fromString(id)).readBytes()).toTimeZoneRules()
Expand All @@ -16,19 +16,6 @@ internal class TzdbOnFilesystem(defaultTzdbPath: Path): TimezoneDatabase {
tzdbPath.traverseDirectory(exclude = tzdbUnneededFiles) { add(it.toString()) }
}

private val tzdbPath = defaultTzdbPath.check()?.let { defaultTzdbPath }
?: pathToSystemDefault()?.first ?: throw IllegalStateException("Could not find the path to the timezone database")

}

internal fun pathToSystemDefault(): Pair<Path, Path>? {
val info = Path(true, listOf("etc", "localtime")).readLink() ?: return null
val i = info.components.indexOf("zoneinfo")
if (!info.isAbsolute || i == -1 || i == info.components.size - 1) return null
return Pair(
Path(true, info.components.subList(0, i + 1)),
Path(false, info.components.subList(i + 1, info.components.size))
)
}

private val tzdbUnneededFiles = setOf(
Expand Down

0 comments on commit 6448e6f

Please sign in to comment.