Skip to content

Commit d3238e9

Browse files
committed
Copy the commonKotlin Instant implementation to kotlinx.time
1 parent 75ba185 commit d3238e9

File tree

7 files changed

+564
-18
lines changed

7 files changed

+564
-18
lines changed

fake-kotlinx-time/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ java {
1313
}
1414

1515
kotlin {
16+
explicitApi()
1617
infra {
1718
target("linuxX64")
1819
target("linuxArm64")

fake-kotlinx-time/common/src/Instant.kt

+474-18
Large diffs are not rendered by default.

fake-kotlinx-time/js/src/Platform.kt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright 2019-2024 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.time
7+
8+
import kotlin.js.Date
9+
10+
internal actual fun currentTime(): Instant = Instant.fromEpochMilliseconds(Date().getTime().toLong())

fake-kotlinx-time/jvm/src/Platform.kt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright 2019-2024 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.time
7+
8+
internal actual fun currentTime(): Instant = java.time.Instant.now().toKotlinInstant()
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2019-2024 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.time
7+
import kotlinx.cinterop.*
8+
import platform.posix.*
9+
10+
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
11+
internal actual fun currentTime(): Instant = memScoped {
12+
val tm = alloc<timespec>()
13+
val error = clock_gettime(CLOCK_REALTIME.convert(), tm.ptr)
14+
check(error == 0) { "Error when reading the system clock: ${strerror(errno)?.toKString() ?: "Unknown error"}" }
15+
try {
16+
require(tm.tv_nsec in 0 until NANOS_PER_ONE)
17+
Instant(tm.tv_sec.convert(), tm.tv_nsec.convert())
18+
} catch (e: IllegalArgumentException) {
19+
throw IllegalStateException("The readings from the system clock (${tm.tv_sec} seconds, ${tm.tv_nsec} nanoseconds) are not representable as an Instant")
20+
}
21+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright 2019-2024 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.time
7+
8+
internal actual fun currentTime(): Instant = Instant.fromEpochMilliseconds(Date().getTime().toLong())
9+
10+
private external class Date {
11+
fun getTime(): Double
12+
}
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2019-2024 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.time
7+
8+
import kotlin.wasm.WasmImport
9+
import kotlin.wasm.unsafe.UnsafeWasmMemoryApi
10+
import kotlin.wasm.unsafe.withScopedMemoryAllocator
11+
12+
/**
13+
* Return the time value of a clock. Note: This is similar to `clock_gettime` in POSIX.
14+
*/
15+
@WasmImport("wasi_snapshot_preview1", "clock_time_get")
16+
private external fun wasiRawClockTimeGet(clockId: Int, precision: Long, resultPtr: Int): Int
17+
18+
private const val CLOCKID_REALTIME = 0
19+
20+
@OptIn(UnsafeWasmMemoryApi::class)
21+
private fun clockTimeGet(): Long = withScopedMemoryAllocator { allocator ->
22+
val rp0 = allocator.allocate(8)
23+
val ret = wasiRawClockTimeGet(
24+
clockId = CLOCKID_REALTIME,
25+
precision = 1,
26+
resultPtr = rp0.address.toInt()
27+
)
28+
if (ret == 0) {
29+
rp0.loadLong()
30+
} else {
31+
error("WASI call failed with $ret")
32+
}
33+
}
34+
35+
internal actual fun currentTime(): Instant = clockTimeGet().let { time ->
36+
// Instant.MAX and Instant.MIN are never going to be exceeded using just the Long number of nanoseconds
37+
Instant(time.floorDiv(NANOS_PER_ONE.toLong()), time.mod(NANOS_PER_ONE.toLong()).toInt())
38+
}

0 commit comments

Comments
 (0)