@@ -28,8 +28,8 @@ internal val localDateParser: Parser<LocalDate>
28
28
}
29
29
}
30
30
31
- private const val YEAR_MIN = - 999_999_999
32
- private const val YEAR_MAX = 999_999_999
31
+ internal const val YEAR_MIN = - 999_999
32
+ internal const val YEAR_MAX = 999_999
33
33
34
34
private fun isValidYear (year : Int ): Boolean =
35
35
year >= YEAR_MIN && year <= YEAR_MAX
@@ -58,44 +58,44 @@ public actual class LocalDate actual constructor(actual val year: Int, actual va
58
58
/* *
59
59
* @throws IllegalArgumentException if the result exceeds the boundaries
60
60
*/
61
- internal fun ofEpochDay (epochDay : Long ): LocalDate {
61
+ internal fun ofEpochDay (epochDay : Int ): LocalDate {
62
+ // LocalDate(-999999, 1, 1).toEpochDay(), LocalDate(999999, 12, 31).toEpochDay()
62
63
// Unidiomatic code due to https://github.com/Kotlin/kotlinx-datetime/issues/5
63
- require(epochDay >= - 365243219162L && epochDay <= 365241780471L ) {
64
+ require(epochDay >= - 365961662 && epochDay <= 364522971 ) {
64
65
" Invalid date: boundaries of LocalDate exceeded"
65
66
}
66
- var zeroDay: Long = epochDay + DAYS_0000_TO_1970
67
+ var zeroDay = epochDay + DAYS_0000_TO_1970
67
68
// find the march-based year
68
69
zeroDay - = 60 // adjust to 0000-03-01 so leap day is at end of four year cycle
69
70
70
- var adjust: Long = 0
71
+ var adjust = 0
71
72
if (zeroDay < 0 ) { // adjust negative years to positive for calculation
72
- val adjustCycles: Long = (zeroDay + 1 ) / DAYS_PER_CYCLE - 1
73
+ val adjustCycles = (zeroDay + 1 ) / DAYS_PER_CYCLE - 1
73
74
adjust = adjustCycles * 400
74
75
zeroDay + = - adjustCycles * DAYS_PER_CYCLE
75
76
}
76
- var yearEst: Long = (400 * zeroDay + 591 ) / DAYS_PER_CYCLE
77
+ var yearEst = (( 400 * zeroDay.toLong() + 591 ) / DAYS_PER_CYCLE ).toInt()
77
78
var doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400 )
78
79
if (doyEst < 0 ) { // fix estimate
79
80
yearEst--
80
81
doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400 )
81
82
}
82
83
yearEst + = adjust // reset any negative year
83
84
84
- val marchDoy0 = doyEst.toInt()
85
+ val marchDoy0 = doyEst
85
86
86
87
// convert march-based values back to january-based
87
88
val marchMonth0 = (marchDoy0 * 5 + 2 ) / 153
88
89
val month = (marchMonth0 + 2 ) % 12 + 1
89
90
val dom = marchDoy0 - (marchMonth0 * 306 + 5 ) / 10 + 1
90
- yearEst + = marchMonth0 / 10 .toLong()
91
- val year: Int = yearEst.toInt()
91
+ yearEst + = marchMonth0 / 10
92
92
93
- return LocalDate (year , month, dom)
93
+ return LocalDate (yearEst , month, dom)
94
94
}
95
95
}
96
96
97
97
// org.threeten.bp.LocalDate#toEpochDay
98
- internal fun toEpochDay (): Long {
98
+ internal fun toEpochDay (): Int {
99
99
val y = year
100
100
val m = monthNumber
101
101
var total = 0
@@ -129,7 +129,7 @@ public actual class LocalDate actual constructor(actual val year: Int, actual va
129
129
// org.threeten.bp.LocalDate#getDayOfWeek
130
130
actual val dayOfWeek: DayOfWeek
131
131
get() {
132
- val dow0 = floorMod(toEpochDay() + 3 , 7 ).toInt()
132
+ val dow0 = floorMod(toEpochDay() + 3 , 7 )
133
133
return DayOfWeek (dow0 + 1 )
134
134
}
135
135
@@ -164,55 +164,42 @@ public actual class LocalDate actual constructor(actual val year: Int, actual va
164
164
* @throws IllegalArgumentException if the result exceeds the boundaries
165
165
* @throws ArithmeticException if arithmetic overflow occurs
166
166
*/
167
- internal fun plusYears (yearsToAdd : Long ): LocalDate {
168
- if (yearsToAdd == 0L ) {
169
- return this
170
- }
171
- val newYear = safeAdd(year.toLong(), yearsToAdd)
172
- if (newYear < Int .MIN_VALUE || newYear > Int .MAX_VALUE ) {
173
- throw ArithmeticException (" Addition overflows an Int" )
174
- }
175
- return resolvePreviousValid(newYear.toInt(), monthNumber, dayOfMonth)
176
- }
167
+ internal fun plusYears (yearsToAdd : Int ): LocalDate =
168
+ if (yearsToAdd == 0 ) this
169
+ else resolvePreviousValid(safeAdd(year, yearsToAdd), monthNumber, dayOfMonth)
177
170
178
171
// org.threeten.bp.LocalDate#plusMonths
179
172
/* *
180
173
* @throws IllegalArgumentException if the result exceeds the boundaries
181
174
* @throws ArithmeticException if arithmetic overflow occurs
182
175
*/
183
- internal fun plusMonths (monthsToAdd : Long ): LocalDate {
184
- if (monthsToAdd == 0L ) {
176
+ internal fun plusMonths (monthsToAdd : Int ): LocalDate {
177
+ if (monthsToAdd == 0 ) {
185
178
return this
186
179
}
187
- val monthCount: Long = year * 12L + (monthNumber - 1 )
180
+ val monthCount = year * 12 + (monthNumber - 1 )
188
181
val calcMonths = safeAdd(monthCount, monthsToAdd)
189
182
val newYear = floorDiv(calcMonths, 12 )
190
- if (newYear < Int .MIN_VALUE || newYear > Int .MAX_VALUE ) {
191
- throw ArithmeticException (" Addition overflows an Int" )
192
- }
193
- val newMonth = floorMod(calcMonths, 12 ).toInt() + 1
194
- return resolvePreviousValid(newYear.toInt(), newMonth, dayOfMonth)
183
+ val newMonth = floorMod(calcMonths, 12 ) + 1
184
+ return resolvePreviousValid(newYear, newMonth, dayOfMonth)
195
185
}
196
186
197
187
// org.threeten.bp.LocalDate#plusWeeks
198
188
/* *
199
189
* @throws IllegalArgumentException if the result exceeds the boundaries
200
190
* @throws ArithmeticException if arithmetic overflow occurs
201
191
*/
202
- internal fun plusWeeks (value : Long ): LocalDate =
192
+ internal fun plusWeeks (value : Int ): LocalDate =
203
193
plusDays(safeMultiply(value, 7 ))
204
194
205
195
// org.threeten.bp.LocalDate#plusDays
206
196
/* *
207
197
* @throws IllegalArgumentException if the result exceeds the boundaries
208
198
* @throws ArithmeticException if arithmetic overflow occurs
209
199
*/
210
- internal fun plusDays (daysToAdd : Long ): LocalDate =
211
- if (daysToAdd == 0L ) {
212
- this
213
- } else {
214
- ofEpochDay(safeAdd(toEpochDay(), daysToAdd))
215
- }
200
+ internal fun plusDays (daysToAdd : Int ): LocalDate =
201
+ if (daysToAdd == 0 ) this
202
+ else ofEpochDay(safeAdd(toEpochDay(), daysToAdd))
216
203
217
204
override fun equals (other : Any? ): Boolean =
218
205
this == = other || (other is LocalDate && compareTo(other) == 0 )
@@ -253,61 +240,60 @@ public actual class LocalDate actual constructor(actual val year: Int, actual va
253
240
}
254
241
255
242
internal actual fun LocalDate.plus (value : Long , unit : CalendarUnit ): LocalDate =
256
- if (unit.dateTimeUnit is DateTimeUnit . DateBased )
257
- plusDateTimeUnit(value, unit.dateTimeUnit as DateTimeUnit . DateBased )
258
- else throw IllegalArgumentException ( " Only date based units can be added to LocalDate " )
243
+ if (value > Int . MAX_VALUE || value < Int . MIN_VALUE )
244
+ throw DateTimeArithmeticException ( " Can't add a Long to a LocalDate " )
245
+ else plus(value.toInt(), unit )
259
246
260
- internal fun LocalDate.plusDateTimeUnit (value : Long , unit : DateTimeUnit .DateBased ): LocalDate =
247
+ internal actual fun LocalDate.plus (value : Int , unit : CalendarUnit ): LocalDate =
248
+ if (unit.dateTimeUnit !is DateTimeUnit .DateBased )
249
+ throw IllegalArgumentException (" Only date based units can be added to LocalDate" )
250
+ else plusDateTimeUnit(value, unit.dateTimeUnit as DateTimeUnit .DateBased )
251
+
252
+ internal fun LocalDate.plusDateTimeUnit (value : Int , unit : DateTimeUnit .DateBased ): LocalDate =
261
253
try {
262
254
when (unit) {
263
- is DateTimeUnit .DateBased .DayBased -> plusDays(safeMultiply(value, unit.days.toLong() ))
264
- is DateTimeUnit .DateBased .MonthBased -> plusMonths(safeMultiply(value, unit.months.toLong() ))
255
+ is DateTimeUnit .DateBased .DayBased -> plusDays(safeMultiply(value, unit.days))
256
+ is DateTimeUnit .DateBased .MonthBased -> plusMonths(safeMultiply(value, unit.months))
265
257
}
266
258
} catch (e: ArithmeticException ) {
267
259
throw DateTimeArithmeticException (" Arithmetic overflow when adding a value to a date" , e)
268
260
} catch (e: IllegalArgumentException ) {
269
261
throw DateTimeArithmeticException (" Boundaries of LocalDate exceeded when adding a value" , e)
270
262
}
271
263
272
- internal actual fun LocalDate.plus (value : Int , unit : CalendarUnit ): LocalDate =
273
- plus(value.toLong(), unit)
274
-
275
264
actual operator fun LocalDate.plus (period : DatePeriod ): LocalDate =
276
265
with (period) {
277
266
try {
278
267
this @plus
279
- .run { if (years != 0 && months == 0 ) plusYears(years.toLong() ) else this }
280
- .run { if (months != 0 ) plusMonths(years * 12L + months.toLong( )) else this }
281
- .run { if (days != 0 ) plusDays(days.toLong() ) else this }
268
+ .run { if (years != 0 && months == 0 ) plusYears(years) else this }
269
+ .run { if (months != 0 ) plusMonths(safeAdd(safeMultiply( years, 12 ), months)) else this }
270
+ .run { if (days != 0 ) plusDays(days) else this }
282
271
} catch (e: ArithmeticException ) {
283
272
throw DateTimeArithmeticException (" Arithmetic overflow when adding a period to a date" , e)
284
273
} catch (e: IllegalArgumentException ) {
285
274
throw DateTimeArithmeticException (" Boundaries of LocalDate exceeded when adding a period" , e)
286
275
}
287
276
}
288
277
289
-
290
- // TODO: ensure range of LocalDate fits in Int number of days
291
- public actual fun LocalDate.daysUntil (other : LocalDate ): Int = longDaysUntil(other).toInt()
292
- public actual fun LocalDate.monthsUntil (other : LocalDate ): Int = longMonthsUntil(other).toInt()
293
- public actual fun LocalDate.yearsUntil (other : LocalDate ): Int = (longMonthsUntil(other) / 12 ).toInt()
294
-
295
278
// org.threeten.bp.LocalDate#daysUntil
296
- internal fun LocalDate.longDaysUntil (other : LocalDate ): Long =
279
+ public actual fun LocalDate.daysUntil (other : LocalDate ): Int =
297
280
other.toEpochDay() - this .toEpochDay()
298
281
299
282
// org.threeten.bp.LocalDate#getProlepticMonth
300
- internal val LocalDate .prolepticMonth get() = (year * 12L ) + (monthNumber - 1 )
283
+ internal val LocalDate .prolepticMonth get() = (year * 12 ) + (monthNumber - 1 )
301
284
302
285
// org.threeten.bp.LocalDate#monthsUntil
303
- internal fun LocalDate.longMonthsUntil (other : LocalDate ): Long {
304
- val packed1: Long = prolepticMonth * 32L + dayOfMonth
305
- val packed2: Long = other.prolepticMonth * 32L + other.dayOfMonth
286
+ public actual fun LocalDate.monthsUntil (other : LocalDate ): Int {
287
+ val packed1 = prolepticMonth * 32 + dayOfMonth
288
+ val packed2 = other.prolepticMonth * 32 + other.dayOfMonth
306
289
return (packed2 - packed1) / 32
307
290
}
308
291
292
+ public actual fun LocalDate.yearsUntil (other : LocalDate ): Int =
293
+ monthsUntil(other) / 12
294
+
309
295
actual fun LocalDate.periodUntil (other : LocalDate ): DatePeriod {
310
- val months = longMonthsUntil (other)
311
- val days = plusMonths(months).longDaysUntil (other)
312
- return DatePeriod (( months / 12 ).toInt(), ( months % 12 ).toInt() , days.toInt() )
296
+ val months = monthsUntil (other)
297
+ val days = plusMonths(months).daysUntil (other)
298
+ return DatePeriod (months / 12 , months % 12 , days)
313
299
}
0 commit comments