Skip to content

Commit 5163e27

Browse files
committed
LocalTime#toSecondOfDay & LocalTime#ofSecondOfDay.
1 parent 4e39fbc commit 5163e27

File tree

5 files changed

+114
-5
lines changed

5 files changed

+114
-5
lines changed

core/common/src/LocalTime.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ public expect class LocalTime : Comparable<LocalTime> {
4040
*/
4141
public fun parse(isoString: String): LocalTime
4242

43+
/**
44+
* Returns a LocalTime with the specified [secondOfDay]. The nanosecond field will be set to zero.
45+
*
46+
* @throws IllegalArgumentException if the boundaries of [secondOfDay] are exceeded.
47+
*/
48+
public fun fromSecondOfDay(secondOfDay: Int): LocalTime
49+
50+
/**
51+
* Returns a LocalTime with the specified [nanosecondOfDay].
52+
*
53+
* @throws IllegalArgumentException if the boundaries of [nanosecondOfDay] are exceeded.
54+
*/
55+
public fun fromNanosecondOfDay(nanosecondOfDay: Long): LocalTime
56+
4357
internal val MIN: LocalTime
4458
internal val MAX: LocalTime
4559
}
@@ -66,6 +80,12 @@ public expect class LocalTime : Comparable<LocalTime> {
6680
/** Returns the nanosecond-of-second time component of this time value. */
6781
public val nanosecond: Int
6882

83+
/** Returns the time as a second of a day, from 0 to 24 * 60 * 60 - 1. */
84+
public val secondOfDay: Int
85+
86+
/** Returns the time as a nanosecond of a day, from 0 to 24 * 60 * 60 * 1000 - 1. */
87+
public val nanosecondOfDay: Long
88+
6989
/**
7090
* Compares `this` time value with the [other] time value.
7191
* Returns zero if this value is equal to the other, a negative number if this value occurs earlier
@@ -110,4 +130,4 @@ public fun LocalTime.atDate(year: Int, month: Month, dayOfMonth: Int = 0): Local
110130
/**
111131
* Combines this time's components with the specified [LocalDate] components into a [LocalDateTime] value.
112132
*/
113-
public fun LocalTime.atDate(date: LocalDate): LocalDateTime = LocalDateTime(date, this)
133+
public fun LocalTime.atDate(date: LocalDate): LocalDateTime = LocalDateTime(date, this)

core/common/test/LocalTimeTest.kt

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
package kotlinx.datetime.test
77

88
import kotlinx.datetime.*
9-
import kotlinx.datetime.Clock
10-
import kotlin.math.min
119
import kotlin.test.*
1210

1311
class LocalTimeTest {
@@ -85,6 +83,58 @@ class LocalTimeTest {
8583
assertFailsWith<IllegalArgumentException> { LocalTime(0, 0, 0, 1_000_000_000) }
8684
}
8785

86+
@Test
87+
fun fromNanosecondOfDay() {
88+
val data = mapOf(
89+
0L to LocalTime(0, 0),
90+
5000000001L to LocalTime(0, 0, 5, 1),
91+
44105000000100L to LocalTime(12, 15, 5, 100),
92+
86399000000999L to LocalTime(23, 59, 59, 999),
93+
)
94+
95+
data.forEach { (nanosecondOfDay, localTime) ->
96+
assertEquals(nanosecondOfDay, localTime.nanosecondOfDay)
97+
assertEquals(localTime, LocalTime.fromNanosecondOfDay(nanosecondOfDay))
98+
}
99+
}
100+
101+
@Test
102+
fun fromNanosecondOfDayInvalid() {
103+
LocalTime.fromNanosecondOfDay(0)
104+
assertFailsWith<IllegalArgumentException> { LocalTime.fromNanosecondOfDay(-1) }
105+
assertFailsWith<IllegalArgumentException> { LocalTime.fromNanosecondOfDay(Long.MAX_VALUE) }
106+
}
107+
108+
@Test
109+
fun fromSecondOfDay() {
110+
val data = mapOf(
111+
0 to LocalTime(0, 0),
112+
5 to LocalTime(0, 0, 5),
113+
44105 to LocalTime(12, 15, 5),
114+
86399 to LocalTime(23, 59, 59),
115+
)
116+
117+
data.forEach { (secondOfDay, localTime) ->
118+
assertEquals(secondOfDay, localTime.secondOfDay)
119+
assertEquals(localTime, LocalTime.fromSecondOfDay(secondOfDay))
120+
}
121+
}
122+
123+
@Test
124+
fun fromSecondOfDayInvalid() {
125+
LocalTime.fromSecondOfDay(0)
126+
assertFailsWith<IllegalArgumentException> { LocalTime.fromSecondOfDay(-1) }
127+
assertFailsWith<IllegalArgumentException> { LocalTime.fromSecondOfDay(Int.MAX_VALUE) }
128+
}
129+
130+
@Test
131+
fun fromSecondOfDayIgnoresNanosecond() {
132+
assertEquals(
133+
0,
134+
LocalTime(0, 0, 0, 100).secondOfDay,
135+
)
136+
}
137+
88138
@Test
89139
fun atDate() {
90140
val time = LocalTime(12, 1, 59)

core/js/src/LocalTime.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public actual class LocalTime internal constructor(internal val value: jtLocalTi
2626
public actual val minute: Int get() = value.minute().toInt()
2727
public actual val second: Int get() = value.second().toInt()
2828
public actual val nanosecond: Int get() = value.nano().toInt()
29+
public actual val secondOfDay: Int get() = value.toSecondOfDay().toInt()
30+
public actual val nanosecondOfDay: Long get() = value.toNanoOfDay().toLong()
2931

3032
override fun equals(other: Any?): Boolean =
3133
(this === other) || (other is LocalTime && this.value == other.value)
@@ -44,7 +46,21 @@ public actual class LocalTime internal constructor(internal val value: jtLocalTi
4446
throw e
4547
}
4648

49+
public actual fun fromSecondOfDay(secondOfDay: Int): LocalTime = try {
50+
jtLocalTime.ofSecondOfDay(secondOfDay, 0).let(::LocalTime)
51+
} catch (e: Throwable) {
52+
if (e.isJodaDateTimeParseException()) throw DateTimeFormatException(e)
53+
throw e
54+
}
55+
56+
public actual fun fromNanosecondOfDay(nanosecondOfDay: Long): LocalTime = try {
57+
jtLocalTime.ofNanoOfDay(nanosecondOfDay).let(::LocalTime)
58+
} catch (e: Throwable) {
59+
if (e.isJodaDateTimeParseException()) throw DateTimeFormatException(e)
60+
throw e
61+
}
62+
4763
internal actual val MIN: LocalTime = LocalTime(jtLocalTime.MIN)
4864
internal actual val MAX: LocalTime = LocalTime(jtLocalTime.MAX)
4965
}
50-
}
66+
}

core/jvm/src/LocalTime.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public actual class LocalTime internal constructor(internal val value: jtLocalTi
2929
public actual val minute: Int get() = value.minute
3030
public actual val second: Int get() = value.second
3131
public actual val nanosecond: Int get() = value.nano
32+
public actual val secondOfDay: Int get() = value.toSecondOfDay()
33+
public actual val nanosecondOfDay: Long get() = value.toNanoOfDay()
3234

3335
override fun equals(other: Any?): Boolean =
3436
(this === other) || (other is LocalTime && this.value == other.value)
@@ -46,7 +48,19 @@ public actual class LocalTime internal constructor(internal val value: jtLocalTi
4648
throw DateTimeFormatException(e)
4749
}
4850

51+
public actual fun fromSecondOfDay(secondOfDay: Int): LocalTime = try {
52+
jtLocalTime.ofSecondOfDay(secondOfDay.toLong()).let(::LocalTime)
53+
} catch (e: DateTimeException) {
54+
throw IllegalArgumentException(e)
55+
}
56+
57+
public actual fun fromNanosecondOfDay(nanosecondOfDay: Long): LocalTime = try {
58+
jtLocalTime.ofNanoOfDay(nanosecondOfDay).let(::LocalTime)
59+
} catch (e: DateTimeException) {
60+
throw IllegalArgumentException(e)
61+
}
62+
4963
internal actual val MIN: LocalTime = LocalTime(jtLocalTime.MIN)
5064
internal actual val MAX: LocalTime = LocalTime(jtLocalTime.MAX)
5165
}
52-
}
66+
}

core/native/src/LocalTime.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ public actual class LocalTime actual constructor(
6262
public actual fun parse(isoString: String): LocalTime =
6363
localTimeParser.parse(isoString)
6464

65+
public actual fun fromSecondOfDay(secondOfDay: Int): LocalTime =
66+
ofSecondOfDay(secondOfDay, 0)
67+
68+
public actual fun fromNanosecondOfDay(nanosecondOfDay: Long): LocalTime =
69+
ofNanoOfDay(nanosecondOfDay)
70+
6571
// org.threeten.bp.LocalTime#ofSecondOfDay(long, int)
6672
internal fun ofSecondOfDay(secondOfDay: Int, nanoOfSecond: Int): LocalTime {
6773
// Unidiomatic code due to https://github.com/Kotlin/kotlinx-datetime/issues/5
@@ -117,6 +123,9 @@ public actual class LocalTime actual constructor(
117123
return (nod xor (nod ushr 32)).toInt()
118124
}
119125

126+
public actual val secondOfDay: Int get() = toSecondOfDay()
127+
public actual val nanosecondOfDay: Long get() = toNanoOfDay()
128+
120129
// org.threeten.bp.LocalTime#toNanoOfDay
121130
internal fun toNanoOfDay(): Long {
122131
var total: Long = hour.toLong() * NANOS_PER_ONE * SECONDS_PER_HOUR

0 commit comments

Comments
 (0)