Skip to content

Commit 24dfa69

Browse files
committed
Simplify
1 parent 6d9c797 commit 24dfa69

File tree

6 files changed

+48
-82
lines changed

6 files changed

+48
-82
lines changed

core/native/src/Instant.kt

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private const val MIN_SECOND = -31619119219200L // -1000000-01-01T00:00:00Z
3636
*/
3737
private const val MAX_SECOND = 31494816403199L // +1000000-12-31T23:59:59
3838

39-
private fun isValidInstantSecond(second: Long) = second >= MIN_SECOND && second <= MAX_SECOND
39+
private fun isValidInstantSecond(second: Long) = second in MIN_SECOND..MAX_SECOND
4040

4141
@Serializable(with = InstantIso8601Serializer::class)
4242
public actual class Instant internal constructor(public actual val epochSeconds: Long, public actual val nanosecondsOfSecond: Int) : Comparable<Instant> {
@@ -54,14 +54,11 @@ public actual class Instant internal constructor(public actual val epochSeconds:
5454
* @throws ArithmeticException if arithmetic overflow occurs
5555
* @throws IllegalArgumentException if the boundaries of Instant are overflown
5656
*/
57-
internal fun plus(secondsToAdd: Long, nanosToAdd: Long): Instant {
58-
if ((secondsToAdd or nanosToAdd) == 0L) {
59-
return this
60-
}
57+
internal fun plus(secondsToAdd: Long, nanosToAdd: Long): Instant = onNonZero(secondsToAdd or nanosToAdd) {
6158
val newEpochSeconds: Long = safeAdd(safeAdd(epochSeconds, secondsToAdd), (nanosToAdd / NANOS_PER_ONE))
6259
val newNanosToAdd = nanosToAdd % NANOS_PER_ONE
6360
val nanoAdjustment = (nanosecondsOfSecond + newNanosToAdd) // safe int+NANOS_PER_ONE
64-
return fromEpochSecondsThrowing(newEpochSeconds, nanoAdjustment)
61+
fromEpochSecondsThrowing(newEpochSeconds, nanoAdjustment)
6562
}
6663

6764
public actual operator fun plus(duration: Duration): Instant = duration.toComponents { secondsToAdd, nanosecondsToAdd ->
@@ -81,10 +78,7 @@ public actual class Instant internal constructor(public actual val epochSeconds:
8178
(this.nanosecondsOfSecond - other.nanosecondsOfSecond).nanoseconds
8279

8380
actual override fun compareTo(other: Instant): Int {
84-
val s = epochSeconds.compareTo(other.epochSeconds)
85-
if (s != 0) {
86-
return s
87-
}
81+
onNonZero(epochSeconds.compareTo(other.epochSeconds)) { return it }
8882
return nanosecondsOfSecond.compareTo(other.nanosecondsOfSecond)
8983
}
9084

@@ -150,27 +144,21 @@ public actual class Instant internal constructor(public actual val epochSeconds:
150144

151145
}
152146

153-
private fun Instant.toLocalDateTimeFailing(offset: UtcOffset): LocalDateTime = try {
154-
toLocalDateTimeImpl(offset)
155-
} catch (e: IllegalArgumentException) {
156-
throw DateTimeArithmeticException("Can not convert instant $this to LocalDateTime to perform computations", e)
157-
}
158-
159147
/** Check that [Instant] fits in [LocalDateTime].
160148
* This is done on the results of computations for consistency with other platforms.
161149
*/
162150
private fun Instant.check(zone: TimeZone): Instant = this@check.also {
163-
toLocalDateTimeFailing(offsetIn(zone))
151+
toLocalDateTime(offsetIn(zone))
164152
}
165153

166154
public actual fun Instant.plus(period: DateTimePeriod, timeZone: TimeZone): Instant = try {
167155
with(period) {
168156
val initialOffset = offsetIn(timeZone)
169-
val newLdt = toLocalDateTimeFailing(initialOffset)
170-
.run { if (totalMonths != 0) { plus(totalMonths, DateTimeUnit.MONTH) } else { this } }
171-
.run { if (days != 0) { plus(days, DateTimeUnit.DAY) } else { this } }
157+
val newLdt = toLocalDateTime(initialOffset)
158+
.run { onNonZero(totalMonths) { plus(it, DateTimeUnit.MONTH) } }
159+
.run { onNonZero(days) { plus(it, DateTimeUnit.DAY) } }
172160
timeZone.localDateTimeToInstant(newLdt, preferred = initialOffset)
173-
.run { if (totalNanoseconds != 0L) plus(0, totalNanoseconds).check(timeZone) else this }
161+
.run { onNonZero(totalNanoseconds) { plus(totalNanoseconds, DateTimeUnit.NANOSECOND).check(timeZone) } }
174162
}.check(timeZone)
175163
} catch (e: ArithmeticException) {
176164
throw DateTimeArithmeticException("Arithmetic overflow when adding CalendarPeriod to an Instant", e)
@@ -191,7 +179,7 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit, timeZone: TimeZo
191179
if (value < Int.MIN_VALUE || value > Int.MAX_VALUE)
192180
throw ArithmeticException("Can't add a Long date-based value, as it would cause an overflow")
193181
val initialOffset = offsetIn(timeZone)
194-
val initialLdt = toLocalDateTimeFailing(initialOffset)
182+
val initialLdt = toLocalDateTime(initialOffset)
195183
timeZone.localDateTimeToInstant(initialLdt.plus(value.toInt(), unit), preferred = initialOffset)
196184
}
197185
is DateTimeUnit.TimeBased ->
@@ -216,13 +204,19 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit.TimeBased): Insta
216204

217205
public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateTimePeriod {
218206
val initialOffset = offsetIn(timeZone)
219-
val initialLdt = toLocalDateTimeFailing(initialOffset)
220-
val otherLdt = other.toLocalDateTimeFailing(other.offsetIn(timeZone))
207+
val initialLdt = toLocalDateTime(initialOffset)
208+
val otherLdt = other.toLocalDateTime(other.offsetIn(timeZone))
221209

222210
val months = initialLdt.until(otherLdt, DateTimeUnit.MONTH) // `until` on dates never fails
223-
val ldtWithMonths = initialLdt.plus(months, DateTimeUnit.MONTH) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
211+
val ldtWithMonths = initialLdt.plus(
212+
months,
213+
DateTimeUnit.MONTH
214+
) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
224215
val days = ldtWithMonths.until(otherLdt, DateTimeUnit.DAY) // `until` on dates never fails
225-
val newInstant = timeZone.localDateTimeToInstant(ldtWithMonths.plus(days, DateTimeUnit.DAY), preferred = initialOffset) // won't throw: thisLdt + days <= otherLdt
216+
val newInstant = timeZone.localDateTimeToInstant(
217+
ldtWithMonths.plus(days, DateTimeUnit.DAY),
218+
preferred = initialOffset
219+
) // won't throw: thisLdt + days <= otherLdt
226220
val nanoseconds = newInstant.until(other, DateTimeUnit.NANOSECOND) // |otherLdt - thisLdt| < 24h
227221

228222
return buildDateTimePeriod(months, days, nanoseconds)
@@ -231,7 +225,7 @@ public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateT
231225
public actual fun Instant.until(other: Instant, unit: DateTimeUnit, timeZone: TimeZone): Long =
232226
when (unit) {
233227
is DateTimeUnit.DateBased ->
234-
toLocalDateTimeFailing(offsetIn(timeZone)).until(other.toLocalDateTimeFailing(other.offsetIn(timeZone)), unit)
228+
toLocalDateTime(offsetIn(timeZone)).until(other.toLocalDateTime(other.offsetIn(timeZone)), unit)
235229
.toLong()
236230
is DateTimeUnit.TimeBased -> {
237231
check(timeZone); other.check(timeZone)

core/native/src/LocalDate.kt

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,8 @@ public actual class LocalDate actual constructor(public actual val year: Int, pu
134134

135135
// Several times faster than using `compareBy`
136136
actual override fun compareTo(other: LocalDate): Int {
137-
val y = year.compareTo(other.year)
138-
if (y != 0) {
139-
return y
140-
}
141-
val m = monthNumber.compareTo(other.monthNumber)
142-
if (m != 0) {
143-
return m
144-
}
137+
onNonZero(year.compareTo(other.year)) { return it }
138+
onNonZero(monthNumber.compareTo(other.monthNumber)) { return it }
145139
return dayOfMonth.compareTo(other.dayOfMonth)
146140
}
147141

@@ -159,15 +153,12 @@ public actual class LocalDate actual constructor(public actual val year: Int, pu
159153
* @throws IllegalArgumentException if the result exceeds the boundaries
160154
* @throws ArithmeticException if arithmetic overflow occurs
161155
*/
162-
internal fun plusMonths(monthsToAdd: Int): LocalDate {
163-
if (monthsToAdd == 0) {
164-
return this
165-
}
156+
internal fun plusMonths(monthsToAdd: Int): LocalDate = onNonZero(monthsToAdd) {
166157
val monthCount = year * 12 + (monthNumber - 1)
167158
val calcMonths = safeAdd(monthCount, monthsToAdd)
168159
val newYear = calcMonths.floorDiv(12)
169160
val newMonth = calcMonths.mod(12) + 1
170-
return resolvePreviousValid(newYear, newMonth, dayOfMonth)
161+
resolvePreviousValid(newYear, newMonth, dayOfMonth)
171162
}
172163

173164
// org.threeten.bp.LocalDate#plusDays
@@ -176,8 +167,7 @@ public actual class LocalDate actual constructor(public actual val year: Int, pu
176167
* @throws ArithmeticException if arithmetic overflow occurs
177168
*/
178169
internal fun plusDays(daysToAdd: Int): LocalDate =
179-
if (daysToAdd == 0) this
180-
else fromEpochDays(safeAdd(toEpochDays(), daysToAdd))
170+
onNonZero(daysToAdd) { fromEpochDays(safeAdd(toEpochDays(), daysToAdd)) }
181171

182172
override fun equals(other: Any?): Boolean =
183173
this === other || (other is LocalDate && compareTo(other) == 0)
@@ -221,8 +211,8 @@ public actual operator fun LocalDate.plus(period: DatePeriod): LocalDate =
221211
with(period) {
222212
try {
223213
this@plus
224-
.run { if (totalMonths != 0) plusMonths(totalMonths) else this }
225-
.run { if (days != 0) plusDays(days) else this }
214+
.run { onNonZero(totalMonths) { plusMonths(it) } }
215+
.run { onNonZero(days) { plusDays(days) } }
226216
} catch (e: ArithmeticException) {
227217
throw DateTimeArithmeticException("Arithmetic overflow when adding a period to a date", e)
228218
} catch (e: IllegalArgumentException) {

core/native/src/LocalDateTime.kt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ public actual constructor(public actual val date: LocalDate, public actual val t
5151

5252
// Several times faster than using `compareBy`
5353
actual override fun compareTo(other: LocalDateTime): Int {
54-
val d = date.compareTo(other.date)
55-
if (d != 0) {
56-
return d
57-
}
54+
onNonZero(date.compareTo(other.date)) { return it }
5855
return time.compareTo(other.time)
5956
}
6057

@@ -112,19 +109,15 @@ internal fun LocalDateTime.until(other: LocalDateTime, unit: DateTimeUnit.TimeBa
112109
* @throws IllegalArgumentException if the result exceeds the boundaries
113110
* @throws ArithmeticException if arithmetic overflow occurs
114111
*/
115-
internal fun LocalDateTime.plusSeconds(seconds: Int): LocalDateTime
116-
{
117-
if (seconds == 0) {
118-
return this
119-
}
112+
internal fun LocalDateTime.plusSeconds(seconds: Int): LocalDateTime = onNonZero(seconds) {
120113
val currentNanoOfDay = time.toNanosecondOfDay() // at most a day
121114
val totalNanos: Long = seconds % SECONDS_PER_DAY * NANOS_PER_ONE.toLong() + // at most a day
122115
currentNanoOfDay
123116
val totalDays = seconds / SECONDS_PER_DAY + // max/24*60*60 < max * 0.000012
124117
totalNanos.floorDiv(NANOS_PER_DAY) // max 2 days
125118
val newNanoOfDay: Long = totalNanos.mod(NANOS_PER_DAY)
126119
val newTime: LocalTime = if (newNanoOfDay == currentNanoOfDay) time else LocalTime.ofNanoOfDay(newNanoOfDay)
127-
return LocalDateTime(date.plusDays(totalDays.toInt()), newTime)
120+
LocalDateTime(date.plusDays(totalDays.toInt()), newTime)
128121
}
129122

130123
private val ISO_DATETIME_OPTIONAL_SECONDS_TRAILING_ZEROS by lazy {

core/native/src/LocalTime.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,9 @@ public actual class LocalTime actual constructor(
8686

8787
// Several times faster than using `compareBy`
8888
actual override fun compareTo(other: LocalTime): Int {
89-
val h = hour.compareTo(other.hour)
90-
if (h != 0) {
91-
return h
92-
}
93-
val m = minute.compareTo(other.minute)
94-
if (m != 0) {
95-
return m
96-
}
97-
val s = second.compareTo(other.second)
98-
if (s != 0) {
99-
return s
100-
}
89+
onNonZero(hour.compareTo(other.hour)) { return it }
90+
onNonZero(minute.compareTo(other.minute)) { return it }
91+
onNonZero(second.compareTo(other.second)) { return it }
10192
return nanosecond.compareTo(other.nanosecond)
10293
}
10394

core/native/src/TimeZone.kt

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,12 @@ public actual open class TimeZone internal constructor() {
5151
) {
5252
val prefix = zoneId.take(3)
5353
val offset = lenientOffsetFormat.parse(zoneId.substring(3))
54-
return when (offset.totalSeconds) {
55-
0 -> FixedOffsetTimeZone(offset, prefix)
56-
else -> FixedOffsetTimeZone(offset, "$prefix$offset")
57-
}
54+
return FixedOffsetTimeZone(offset, prefix.onNonZero(offset.totalSeconds) { "$prefix$offset" })
5855
}
5956
if (zoneId.startsWith("UT+") || zoneId.startsWith("UT-")) {
6057
val offset = lenientOffsetFormat.parse(zoneId.substring(2))
61-
return when (offset.totalSeconds) {
62-
0 -> FixedOffsetTimeZone(offset, "UT")
63-
else -> FixedOffsetTimeZone(offset, "UT$offset")
64-
}
58+
val prefix = "UT"
59+
return FixedOffsetTimeZone(offset, prefix.onNonZero(offset.totalSeconds) { "$prefix$offset"})
6560
}
6661
} catch (e: DateTimeFormatException) {
6762
throw IllegalTimeZoneException(e)
@@ -83,14 +78,11 @@ public actual open class TimeZone internal constructor() {
8378
public actual fun Instant.toLocalDateTime(): LocalDateTime = instantToLocalDateTime(this)
8479
public actual fun LocalDateTime.toInstant(): Instant = localDateTimeToInstant(this)
8580

86-
internal open fun atStartOfDay(date: LocalDate): Instant = error("Should be overridden") //value.atStartOfDay(date)
81+
internal open fun atStartOfDay(date: LocalDate): Instant = error("Should be overridden")
8782
internal open fun offsetAtImpl(instant: Instant): UtcOffset = error("Should be overridden")
8883

89-
internal open fun instantToLocalDateTime(instant: Instant): LocalDateTime = try {
90-
instant.toLocalDateTimeImpl(offsetAtImpl(instant))
91-
} catch (e: IllegalArgumentException) {
92-
throw DateTimeArithmeticException("Instant $instant is not representable as LocalDateTime.", e)
93-
}
84+
internal open fun instantToLocalDateTime(instant: Instant): LocalDateTime =
85+
instant.toLocalDateTime(offsetAtImpl(instant))
9486

9587
internal open fun localDateTimeToInstant(dateTime: LocalDateTime, preferred: UtcOffset? = null): Instant =
9688
error("Should be overridden")
@@ -118,8 +110,6 @@ public actual class FixedOffsetTimeZone internal constructor(public actual val o
118110

119111
override fun localDateTimeToInstant(dateTime: LocalDateTime, preferred: UtcOffset?): Instant =
120112
dateTime.toInstant(offset)
121-
122-
override fun instantToLocalDateTime(instant: Instant): LocalDateTime = instant.toLocalDateTime(offset)
123113
}
124114

125115

core/native/src/internal/util.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright 2019-2023 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.datetime.internal
7+
8+
internal inline fun <A, T: Number> A.onNonZero(value: T, block: (T) -> A): A = if (value != 0) block(value) else this

0 commit comments

Comments
 (0)