@@ -175,7 +175,7 @@ private fun Instant.toZonedDateTimeFailing(zone: TimeZone): ZonedDateTime = try
175175 */
176176private fun Instant.toZonedDateTime (zone : TimeZone ): ZonedDateTime {
177177 val currentOffset = zone.offsetAt(this )
178- return ZonedDateTime (toLocalDateTimeImpl(currentOffset), zone, currentOffset)
178+ return ZonedDateTime (toLocalDateTimeImpl(currentOffset), currentOffset)
179179}
180180
181181/* * Check that [Instant] fits in [ZonedDateTime].
@@ -188,8 +188,8 @@ private fun Instant.check(zone: TimeZone): Instant = this@check.also {
188188public actual fun Instant.plus (period : DateTimePeriod , timeZone : TimeZone ): Instant = try {
189189 with (period) {
190190 val withDate = toZonedDateTimeFailing(timeZone)
191- .run { if (totalMonths != 0L ) plus(totalMonths, DateTimeUnit .MONTH ) else this }
192- .run { if (days != 0 ) plus(days.toLong() , DateTimeUnit .DAY ) else this }
191+ .run { if (totalMonths != 0L ) timeZone.atZone(dateTime. plus(totalMonths, DateTimeUnit .MONTH ), offset ) else this }
192+ .run { if (days != 0 ) timeZone.atZone(dateTime.plus(days , DateTimeUnit .DAY ), offset ) else this }
193193 withDate.toInstant()
194194 .run { if (totalNanoseconds != 0L ) plus(0 , totalNanoseconds).check(timeZone) else this }
195195 }.check(timeZone)
@@ -208,8 +208,13 @@ public actual fun Instant.minus(value: Int, unit: DateTimeUnit, timeZone: TimeZo
208208 plus(- value.toLong(), unit, timeZone)
209209public actual fun Instant.plus (value : Long , unit : DateTimeUnit , timeZone : TimeZone ): Instant = try {
210210 when (unit) {
211- is DateTimeUnit .DateBased ->
212- toZonedDateTimeFailing(timeZone).plus(value, unit).toInstant()
211+ is DateTimeUnit .DateBased -> {
212+ val toZonedDateTimeFailing = toZonedDateTimeFailing(timeZone)
213+ timeZone.atZone(
214+ toZonedDateTimeFailing.dateTime.plus(value, unit),
215+ toZonedDateTimeFailing.offset
216+ ).toInstant()
217+ }
213218 is DateTimeUnit .TimeBased ->
214219 check(timeZone).plus(value, unit).check(timeZone)
215220 }
@@ -234,11 +239,19 @@ public actual fun Instant.periodUntil(other: Instant, timeZone: TimeZone): DateT
234239 var thisLdt = toZonedDateTimeFailing(timeZone)
235240 val otherLdt = other.toZonedDateTimeFailing(timeZone)
236241
237- val months = thisLdt.until(otherLdt, DateTimeUnit .MONTH ) // `until` on dates never fails
238- thisLdt = thisLdt.plus(months, DateTimeUnit .MONTH ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
239- val days = thisLdt.until(otherLdt, DateTimeUnit .DAY ) // `until` on dates never fails
240- thisLdt = thisLdt.plus(days, DateTimeUnit .DAY ) // won't throw: thisLdt + days <= otherLdt
241- val nanoseconds = thisLdt.until(otherLdt, DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
242+ val months = thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .MONTH ) // `until` on dates never fails
243+ thisLdt = timeZone.atZone(
244+ thisLdt.dateTime.plus(months, DateTimeUnit .MONTH ),
245+ thisLdt.offset
246+ ) // won't throw: thisLdt + months <= otherLdt, which is known to be valid
247+ val days =
248+ thisLdt.dateTime.until(otherLdt.dateTime, DateTimeUnit .DAY ) // `until` on dates never fails
249+ thisLdt = timeZone.atZone(
250+ thisLdt.dateTime.plus(days, DateTimeUnit .DAY ),
251+ thisLdt.offset
252+ ) // won't throw: thisLdt + days <= otherLdt
253+ val nanoseconds =
254+ thisLdt.toInstant().until(otherLdt.toInstant(), DateTimeUnit .NANOSECOND ) // |otherLdt - thisLdt| < 24h
242255
243256 return buildDateTimePeriod(months, days.toInt(), nanoseconds)
244257}
@@ -277,3 +290,9 @@ private val ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS = DateTimeComponents.Format
277290 outputSecond = WhenToOutput .IF_NONZERO
278291 )
279292}
293+
294+ private fun LocalDateTime.plus (value : Long , unit : DateTimeUnit .DateBased ) =
295+ date.plus(value, unit).atTime(time)
296+
297+ private fun LocalDateTime.plus (value : Int , unit : DateTimeUnit .DateBased ) =
298+ date.plus(value, unit).atTime(time)
0 commit comments