Skip to content

Commit dbfb009

Browse files
committed
Specialize LocalDate.until to avoid intermediate clamping
1 parent a76d541 commit dbfb009

File tree

5 files changed

+18
-7
lines changed

5 files changed

+18
-7
lines changed

core/commonMain/src/LocalDate.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ expect fun LocalDate.periodUntil(other: LocalDate): DatePeriod
5050
/** */
5151
operator fun LocalDate.minus(other: LocalDate): DatePeriod = other.periodUntil(this)
5252

53+
public expect fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int
54+
5355
public expect fun LocalDate.daysUntil(other: LocalDate): Int
5456
public expect fun LocalDate.monthsUntil(other: LocalDate): Int
5557
public expect fun LocalDate.yearsUntil(other: LocalDate): Int
@@ -68,8 +70,3 @@ public expect fun LocalDate.plus(value: Int, unit: DateTimeUnit.DateBased): Loca
6870
* @throws DateTimeArithmeticException if the result exceeds the boundaries of [LocalDate].
6971
*/
7072
public expect fun LocalDate.plus(value: Long, unit: DateTimeUnit.DateBased): LocalDate
71-
72-
public fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
73-
is DateTimeUnit.DateBased.MonthBased -> monthsUntil(other) / unit.months
74-
is DateTimeUnit.DateBased.DayBased -> daysUntil(other) / unit.days
75-
}

core/commonTest/src/LocalDateTest.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ class LocalDateTest {
144144
val diffDays = LocalDate.MIN.until(LocalDate.MAX, unit1000days)
145145
val diffYears = LocalDate.MIN.until(LocalDate.MAX, unit4years)
146146
assertTrue(diffDays in 0..Int.MAX_VALUE, "difference in $unit1000days should fit in Int, was $diffDays")
147-
// TODO: make pass in JVM
148-
// assertTrue(diffDays > diffYears, "difference in $unit1000days unit must be more than in $unit4years unit, was $diffDays $diffYears")
147+
assertTrue(diffDays > diffYears, "difference in $unit1000days unit must be more than in $unit4years unit, was $diffDays $diffYears")
149148
}
150149

151150
@Test

core/jsMain/src/LocalDate.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public actual fun LocalDate.periodUntil(other: LocalDate): DatePeriod {
8686
return DatePeriod(months / 12, months % 12, days)
8787
}
8888

89+
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
90+
is DateTimeUnit.DateBased.MonthBased -> monthsUntil(other) / unit.months
91+
is DateTimeUnit.DateBased.DayBased -> daysUntil(other) / unit.days
92+
}
93+
8994
public actual fun LocalDate.daysUntil(other: LocalDate): Int =
9095
this.value.until(other.value, ChronoUnit.DAYS).toInt()
9196

core/jvmMain/src/LocalDate.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public actual fun LocalDate.periodUntil(other: LocalDate): DatePeriod {
100100
return DatePeriod((months / 12).toInt(), (months % 12).toInt(), days.toInt())
101101
}
102102

103+
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
104+
is DateTimeUnit.DateBased.MonthBased -> (this.value.until(other.value, ChronoUnit.MONTHS) / unit.months).clampToInt()
105+
is DateTimeUnit.DateBased.DayBased -> (this.value.until(other.value, ChronoUnit.DAYS) / unit.days).clampToInt()
106+
}
107+
103108
public actual fun LocalDate.daysUntil(other: LocalDate): Int =
104109
this.value.until(other.value, ChronoUnit.DAYS).clampToInt()
105110

core/nativeMain/src/LocalDate.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ actual operator fun LocalDate.plus(period: DatePeriod): LocalDate =
276276
}
277277
}
278278

279+
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
280+
is DateTimeUnit.DateBased.MonthBased -> monthsUntil(other) / unit.months
281+
is DateTimeUnit.DateBased.DayBased -> daysUntil(other) / unit.days
282+
}
283+
279284
// org.threeten.bp.LocalDate#daysUntil
280285
public actual fun LocalDate.daysUntil(other: LocalDate): Int =
281286
other.toEpochDay() - this.toEpochDay()

0 commit comments

Comments
 (0)