@@ -165,7 +165,7 @@ private fun Instant.toZonedDateTimeFailing(zone: TimeZone): ZonedDateTime = try
165165 */
166166private fun Instant.toZonedDateTime (zone : TimeZone ): ZonedDateTime {
167167 val currentOffset = zone.offsetAt(this )
168- return ZonedDateTime (toLocalDateTimeImpl(currentOffset), zone, currentOffset)
168+ return ZonedDateTime (toLocalDateTimeImpl(currentOffset), currentOffset)
169169}
170170
171171/* * Check that [Instant] fits in [ZonedDateTime].
@@ -178,8 +178,8 @@ private fun Instant.check(zone: TimeZone): Instant = this@check.also {
178178public actual fun Instant.plus (period : DateTimePeriod , timeZone : TimeZone ): Instant = try {
179179 with (period) {
180180 val withDate = toZonedDateTimeFailing(timeZone)
181- .run { if (totalMonths != 0L ) plus(totalMonths, DateTimeUnit .MONTH ) else this }
182- .run { if (days != 0 ) plus(days.toLong() , DateTimeUnit .DAY ) else this }
181+ .run { if (totalMonths != 0L ) timeZone.atZone(dateTime. plus(totalMonths, DateTimeUnit .MONTH ), offset ) else this }
182+ .run { if (days != 0 ) timeZone.atZone(dateTime.plus(days , DateTimeUnit .DAY ), offset ) else this }
183183 withDate.toInstant()
184184 .run { if (totalNanoseconds != 0L ) plus(0 , totalNanoseconds).check(timeZone) else this }
185185 }.check(timeZone)
@@ -198,8 +198,13 @@ public actual fun Instant.minus(value: Int, unit: DateTimeUnit, timeZone: TimeZo
198198 plus(- value.toLong(), unit, timeZone)
199199public actual fun Instant.plus (value : Long , unit : DateTimeUnit , timeZone : TimeZone ): Instant = try {
200200 when (unit) {
201- is DateTimeUnit .DateBased ->
202- toZonedDateTimeFailing(timeZone).plus(value, unit).toInstant()
201+ is DateTimeUnit .DateBased -> {
202+ val toZonedDateTimeFailing = toZonedDateTimeFailing(timeZone)
203+ timeZone.atZone(
204+ toZonedDateTimeFailing.dateTime.plus(value, unit),
205+ toZonedDateTimeFailing.offset
206+ ).toInstant()
207+ }
203208 is DateTimeUnit .TimeBased ->
204209 check(timeZone).plus(value, unit).check(timeZone)
205210 }
@@ -224,11 +229,19 @@ public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateT
224229 var thisLdt = toZonedDateTimeFailing(timeZone)
225230 val otherLdt = other.toZonedDateTimeFailing(timeZone)
226231
227- val months = thisLdt.until(otherLdt, DateTimeUnit .MONTH ) // `until` on dates never fails
228- thisLdt = thisLdt.plus(months, DateTimeUnit .MONTH ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
229- val days = thisLdt.until(otherLdt, DateTimeUnit .DAY ) // `until` on dates never fails
230- thisLdt = thisLdt.plus(days, DateTimeUnit .DAY ) // won't throw: thisLdt + days <= otherLdt
231- val nanoseconds = thisLdt.until(otherLdt, DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
232+ val months = thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .MONTH ) // `until` on dates never fails
233+ thisLdt = timeZone.atZone(
234+ thisLdt.dateTime.plus(months, DateTimeUnit .MONTH ),
235+ thisLdt.offset
236+ ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
237+ val days =
238+ thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .DAY ) // `until` on dates never fails
239+ thisLdt = timeZone.atZone(
240+ thisLdt.dateTime.plus(days, DateTimeUnit .DAY ),
241+ thisLdt.offset
242+ ) // won't throw: thisLdt + days <= otherLdt
243+ val nanoseconds =
244+ thisLdt.toInstant().until(otherLdt.toInstant(), DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
232245
233246 return buildDateTimePeriod(months, days.toInt(), nanoseconds)
234247}
@@ -267,3 +280,9 @@ private val ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS = DateTimeComponents.Format
267280 outputSecond = WhenToOutput .IF_NONZERO
268281 )
269282}
283+
284+ private fun LocalDateTime.plus (value : Long , unit : DateTimeUnit .DateBased ) =
285+ date.plus(value, unit).atTime(time)
286+
287+ private fun LocalDateTime.plus (value : Int , unit : DateTimeUnit .DateBased ) =
288+ date.plus(value, unit).atTime(time)
0 commit comments