[WASM] Implement std kotlin.time
This commit is contained in:
@@ -1,9 +1,38 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kotlin.time
|
package kotlin.time
|
||||||
|
|
||||||
|
import kotlin.math.*
|
||||||
|
|
||||||
internal actual inline val durationAssertionsEnabled: Boolean get() = true
|
internal actual inline val durationAssertionsEnabled: Boolean get() = true
|
||||||
internal actual fun formatToExactDecimals(value: Double, decimals: Int): String = TODO("Wasm stdlib: Duration")
|
|
||||||
internal actual fun formatUpToDecimals(value: Double, decimals: Int): String = TODO("Wasm stdlib: Duration")
|
@JsFun("(value, decimals) => value.toFixed(decimals)")
|
||||||
|
private external fun toFixed(value: Double, decimals: Int): String
|
||||||
|
|
||||||
|
@JsFun("(value, decimals) => value.toPrecision(decimals)")
|
||||||
|
private external fun toPrecision(value: Double, decimals: Int): String
|
||||||
|
|
||||||
|
internal actual fun formatToExactDecimals(value: Double, decimals: Int): String {
|
||||||
|
val rounded = if (decimals == 0) {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
val pow = (10.0).pow(decimals)
|
||||||
|
round(abs(value) * pow) / pow * sign(value)
|
||||||
|
round(abs(value) * pow) / pow * sign(value)
|
||||||
|
}
|
||||||
|
return if (abs(rounded) < 1e21) {
|
||||||
|
// toFixed switches to scientific format after 1e21
|
||||||
|
toFixed(rounded, decimals)
|
||||||
|
} else {
|
||||||
|
// toPrecision outputs the specified number of digits, but only for positive numbers
|
||||||
|
val positive = abs(rounded)
|
||||||
|
val positiveString = toPrecision(positive, ceil(log10(positive)).toInt() + decimals)
|
||||||
|
if (rounded < 0) "-$positiveString" else positiveString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsFun("(value, decimals) => value.toLocaleString(\"en-us\", ({\"maximumFractionDigits\": decimals}))")
|
||||||
|
external internal actual fun formatUpToDecimals(value: Double, decimals: Int): String
|
||||||
@@ -1,55 +1,77 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kotlin.time
|
package kotlin.time
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of possible time measurement units, in which a duration can be expressed.
|
|
||||||
*
|
|
||||||
* The smallest time unit is [NANOSECONDS] and the largest is [DAYS], which corresponds to exactly 24 [HOURS].
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.6")
|
@SinceKotlin("1.6")
|
||||||
@WasExperimental(ExperimentalTime::class)
|
@WasExperimental(ExperimentalTime::class)
|
||||||
public actual enum class DurationUnit {
|
public actual enum class DurationUnit(internal val scale: Double) {
|
||||||
/**
|
/**
|
||||||
* Time unit representing one nanosecond, which is 1/1000 of a microsecond.
|
* Time unit representing one nanosecond, which is 1/1000 of a microsecond.
|
||||||
*/
|
*/
|
||||||
NANOSECONDS,
|
NANOSECONDS(1e0),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one microsecond, which is 1/1000 of a millisecond.
|
* Time unit representing one microsecond, which is 1/1000 of a millisecond.
|
||||||
*/
|
*/
|
||||||
MICROSECONDS,
|
MICROSECONDS(1e3),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one millisecond, which is 1/1000 of a second.
|
* Time unit representing one millisecond, which is 1/1000 of a second.
|
||||||
*/
|
*/
|
||||||
MILLISECONDS,
|
MILLISECONDS(1e6),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one second.
|
* Time unit representing one second.
|
||||||
*/
|
*/
|
||||||
SECONDS,
|
SECONDS(1e9),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one minute.
|
* Time unit representing one minute.
|
||||||
*/
|
*/
|
||||||
MINUTES,
|
MINUTES(60e9),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one hour.
|
* Time unit representing one hour.
|
||||||
*/
|
*/
|
||||||
HOURS,
|
HOURS(3600e9),
|
||||||
/**
|
/**
|
||||||
* Time unit representing one day, which is always equal to 24 hours.
|
* Time unit representing one day, which is always equal to 24 hours.
|
||||||
*/
|
*/
|
||||||
DAYS;
|
DAYS(86400e9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Converts the given time duration [value] expressed in the specified [sourceUnit] into the specified [targetUnit]. */
|
|
||||||
@SinceKotlin("1.3")
|
@SinceKotlin("1.3")
|
||||||
internal actual fun convertDurationUnit(value: Double, sourceUnit: DurationUnit, targetUnit: DurationUnit): Double = TODO("Wasm stdlib: convertDurationUnit Double")
|
internal actual fun convertDurationUnit(value: Double, sourceUnit: DurationUnit, targetUnit: DurationUnit): Double {
|
||||||
|
val sourceCompareTarget = sourceUnit.scale.compareTo(targetUnit.scale)
|
||||||
|
return when {
|
||||||
|
sourceCompareTarget > 0 -> value * (sourceUnit.scale / targetUnit.scale)
|
||||||
|
sourceCompareTarget < 0 -> value / (targetUnit.scale / sourceUnit.scale)
|
||||||
|
else -> value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SinceKotlin("1.5")
|
@SinceKotlin("1.5")
|
||||||
internal actual fun convertDurationUnitOverflow(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long = TODO("Wasm stdlib: convertDurationUnitOverflow Long")
|
internal actual fun convertDurationUnitOverflow(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long {
|
||||||
|
val sourceCompareTarget = sourceUnit.scale.compareTo(targetUnit.scale)
|
||||||
|
return when {
|
||||||
|
sourceCompareTarget > 0 -> value * (sourceUnit.scale / targetUnit.scale).toLong()
|
||||||
|
sourceCompareTarget < 0 -> value / (targetUnit.scale / sourceUnit.scale).toLong()
|
||||||
|
else -> value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SinceKotlin("1.5")
|
@SinceKotlin("1.5")
|
||||||
internal actual fun convertDurationUnit(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long = TODO("Wasm stdlib: convertDurationUnit Long")
|
internal actual fun convertDurationUnit(value: Long, sourceUnit: DurationUnit, targetUnit: DurationUnit): Long {
|
||||||
|
val sourceCompareTarget = sourceUnit.scale.compareTo(targetUnit.scale)
|
||||||
|
return when {
|
||||||
|
sourceCompareTarget > 0 -> {
|
||||||
|
val scale = (sourceUnit.scale / targetUnit.scale).toLong()
|
||||||
|
val result = value * scale
|
||||||
|
when {
|
||||||
|
result / scale == value -> result
|
||||||
|
value > 0 -> Long.MAX_VALUE
|
||||||
|
else -> Long.MIN_VALUE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceCompareTarget < 0 -> value / (targetUnit.scale / sourceUnit.scale).toLong()
|
||||||
|
else -> value
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,29 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package kotlin.time
|
package kotlin.time
|
||||||
|
|
||||||
|
import kotlin.wasm.internal.ExternalInterfaceType
|
||||||
|
|
||||||
|
@JsFun("() => typeof globalThis !== 'undefined' && typeof globalThis.performance !== 'undefined' ? globalThis.performance : null")
|
||||||
|
private external fun tryGetPerformance(): ExternalInterfaceType?
|
||||||
|
|
||||||
|
@JsFun("(performance) => performance.now()")
|
||||||
|
private external fun getPerformanceNow(performance: ExternalInterfaceType): Double
|
||||||
|
|
||||||
|
@JsFun("() => Date.now()")
|
||||||
|
private external fun dateNow(): Double
|
||||||
|
|
||||||
@SinceKotlin("1.3")
|
@SinceKotlin("1.3")
|
||||||
@ExperimentalTime
|
@ExperimentalTime
|
||||||
internal actual object MonotonicTimeSource : TimeSource {
|
internal actual object MonotonicTimeSource : TimeSource, AbstractDoubleTimeSource(unit = DurationUnit.MILLISECONDS) {
|
||||||
override fun markNow(): TimeMark = TODO("Wasm stdlib: MonotonicTimeSource::markNow")
|
private val performance: ExternalInterfaceType? = tryGetPerformance()
|
||||||
|
|
||||||
|
override fun read(): Double =
|
||||||
|
if (performance != null) getPerformanceNow(performance) else dateNow()
|
||||||
|
|
||||||
|
override fun toString(): String =
|
||||||
|
if (performance != null) "TimeSource(globalThis.performance.now())" else "TimeSource(Date.now())"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user