@@ -36,7 +36,7 @@ private const val MIN_SECOND = -31619119219200L // -1000000-01-01T00:00:00Z
36
36
*/
37
37
private const val MAX_SECOND = 31494816403199L // +1000000-12-31T23:59:59
38
38
39
- private fun isValidInstantSecond (second : Long ) = second >= MIN_SECOND && second <= MAX_SECOND
39
+ private fun isValidInstantSecond (second : Long ) = second in MIN_SECOND .. MAX_SECOND
40
40
41
41
@Serializable(with = InstantIso8601Serializer ::class )
42
42
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:
54
54
* @throws ArithmeticException if arithmetic overflow occurs
55
55
* @throws IllegalArgumentException if the boundaries of Instant are overflown
56
56
*/
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) {
61
58
val newEpochSeconds: Long = safeAdd(safeAdd(epochSeconds, secondsToAdd), (nanosToAdd / NANOS_PER_ONE ))
62
59
val newNanosToAdd = nanosToAdd % NANOS_PER_ONE
63
60
val nanoAdjustment = (nanosecondsOfSecond + newNanosToAdd) // safe int+NANOS_PER_ONE
64
- return fromEpochSecondsThrowing(newEpochSeconds, nanoAdjustment)
61
+ fromEpochSecondsThrowing(newEpochSeconds, nanoAdjustment)
65
62
}
66
63
67
64
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:
81
78
(this .nanosecondsOfSecond - other.nanosecondsOfSecond).nanoseconds
82
79
83
80
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 }
88
82
return nanosecondsOfSecond.compareTo(other.nanosecondsOfSecond)
89
83
}
90
84
@@ -150,27 +144,21 @@ public actual class Instant internal constructor(public actual val epochSeconds:
150
144
151
145
}
152
146
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
-
159
147
/* * Check that [Instant] fits in [LocalDateTime].
160
148
* This is done on the results of computations for consistency with other platforms.
161
149
*/
162
150
private fun Instant.check (zone : TimeZone ): Instant = this @check.also {
163
- toLocalDateTimeFailing (offsetIn(zone))
151
+ toLocalDateTime (offsetIn(zone))
164
152
}
165
153
166
154
public actual fun Instant.plus (period : DateTimePeriod , timeZone : TimeZone ): Instant = try {
167
155
with (period) {
168
156
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 ) } }
172
160
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) } }
174
162
}.check(timeZone)
175
163
} catch (e: ArithmeticException ) {
176
164
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
191
179
if (value < Int .MIN_VALUE || value > Int .MAX_VALUE )
192
180
throw ArithmeticException (" Can't add a Long date-based value, as it would cause an overflow" )
193
181
val initialOffset = offsetIn(timeZone)
194
- val initialLdt = toLocalDateTimeFailing (initialOffset)
182
+ val initialLdt = toLocalDateTime (initialOffset)
195
183
timeZone.localDateTimeToInstant(initialLdt.plus(value.toInt(), unit), preferred = initialOffset)
196
184
}
197
185
is DateTimeUnit .TimeBased ->
@@ -216,13 +204,19 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit.TimeBased): Insta
216
204
217
205
public actual fun Instant.periodUntil (other : Instant , timeZone : TimeZone ): DateTimePeriod {
218
206
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))
221
209
222
210
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
224
215
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
226
220
val nanoseconds = newInstant.until(other, DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
227
221
228
222
return buildDateTimePeriod(months, days, nanoseconds)
@@ -231,7 +225,7 @@ public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateT
231
225
public actual fun Instant.until (other : Instant , unit : DateTimeUnit , timeZone : TimeZone ): Long =
232
226
when (unit) {
233
227
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)
235
229
.toLong()
236
230
is DateTimeUnit .TimeBased -> {
237
231
check(timeZone); other.check(timeZone)
0 commit comments