@@ -10,7 +10,6 @@ package kotlinx.datetime
10
10
11
11
import kotlinx.cinterop.*
12
12
import kotlinx.datetime.internal.*
13
- import kotlinx.datetime.optional
14
13
import kotlinx.datetime.serializers.InstantIso8601Serializer
15
14
import kotlinx.serialization.Serializable
16
15
import platform.posix.*
@@ -264,7 +263,7 @@ private fun Instant.toZonedDateTimeFailing(zone: TimeZone): ZonedDateTime = try
264
263
*/
265
264
private fun Instant.toZonedDateTime (zone : TimeZone ): ZonedDateTime {
266
265
val currentOffset = zone.offsetAt(this )
267
- return ZonedDateTime (toLocalDateTimeImpl(currentOffset), zone, currentOffset)
266
+ return ZonedDateTime (toLocalDateTimeImpl(currentOffset), currentOffset)
268
267
}
269
268
270
269
/* * Check that [Instant] fits in [ZonedDateTime].
@@ -277,8 +276,8 @@ private fun Instant.check(zone: TimeZone): Instant =
[email protected] {
277
276
public actual fun Instant.plus (period : DateTimePeriod , timeZone : TimeZone ): Instant = try {
278
277
with (period) {
279
278
val withDate = toZonedDateTimeFailing(timeZone)
280
- .run { if (totalMonths != 0 ) plus(totalMonths, DateTimeUnit .MONTH ) else this }
281
- .run { if (days != 0 ) plus(days, DateTimeUnit .DAY ) else this }
279
+ .run { if (totalMonths != 0 ) timeZone.atZone(dateTime. plus(totalMonths, DateTimeUnit .MONTH ), offset ) else this }
280
+ .run { if (days != 0 ) timeZone.atZone(dateTime. plus(days, DateTimeUnit .DAY ), offset ) else this }
282
281
withDate.toInstant()
283
282
.run { if (totalNanoseconds != 0L ) plus(0 , totalNanoseconds).check(timeZone) else this }
284
283
}.check(timeZone)
@@ -300,7 +299,11 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit, timeZone: TimeZo
300
299
is DateTimeUnit .DateBased -> {
301
300
if (value < Int .MIN_VALUE || value > Int .MAX_VALUE )
302
301
throw ArithmeticException (" Can't add a Long date-based value, as it would cause an overflow" )
303
- toZonedDateTimeFailing(timeZone).plus(value.toInt(), unit).toInstant()
302
+ val toZonedDateTimeFailing = toZonedDateTimeFailing(timeZone)
303
+ timeZone.atZone(
304
+ toZonedDateTimeFailing.dateTime.plus(value.toInt(), unit),
305
+ toZonedDateTimeFailing.offset
306
+ ).toInstant()
304
307
}
305
308
is DateTimeUnit .TimeBased ->
306
309
check(timeZone).plus(value, unit).check(timeZone)
@@ -326,11 +329,20 @@ public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateT
326
329
var thisLdt = toZonedDateTimeFailing(timeZone)
327
330
val otherLdt = other.toZonedDateTimeFailing(timeZone)
328
331
329
- val months = thisLdt.until(otherLdt, DateTimeUnit .MONTH ).toInt() // `until` on dates never fails
330
- thisLdt = thisLdt.plus(months, DateTimeUnit .MONTH ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
331
- val days = thisLdt.until(otherLdt, DateTimeUnit .DAY ).toInt() // `until` on dates never fails
332
- thisLdt = thisLdt.plus(days, DateTimeUnit .DAY ) // won't throw: thisLdt + days <= otherLdt
333
- val nanoseconds = thisLdt.until(otherLdt, DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
332
+ val months =
333
+ thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .MONTH ).toLong().toInt() // `until` on dates never fails
334
+ thisLdt = timeZone.atZone(
335
+ thisLdt.dateTime.plus(months, DateTimeUnit .MONTH ),
336
+ thisLdt.offset
337
+ ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
338
+ val days =
339
+ thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .DAY ).toLong().toInt() // `until` on dates never fails
340
+ thisLdt = timeZone.atZone(
341
+ thisLdt.dateTime.plus(days, DateTimeUnit .DAY ),
342
+ thisLdt.offset
343
+ ) // won't throw: thisLdt + days <= otherLdt
344
+ val nanoseconds =
345
+ thisLdt.toInstant().until(otherLdt.toInstant(), DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
334
346
335
347
return buildDateTimePeriod(months, days, nanoseconds)
336
348
}
0 commit comments