-
Notifications
You must be signed in to change notification settings - Fork 1
Description
One of the CI runs caught this when testing creation of Date from java.time.LocalDate:
[info] Date
[info] - should be created from a LocalDate *** FAILED ***
[info] NoSuchElementException was thrown during property evaluation.
[info] Message: None.get
[info] Occurred when passed generated values (
[info] arg0 = -501945964-02-29
[info] )
Possibly caused by the date 29 of February for the year 501945965 BC. LocalDate seems to try to follow the ISO recommendation (not actual part of the standard) for BC years of starting from the non-existing year 0 as a representation of 1BC, meaning that year -501945964 would be 501945965BC, now the problem is that if we do the following:
scala> LocalDate.parse("-501945964-02-29")
res18: java.time.LocalDate = -501945964-02-29
scala> LocalDate.parse("-501945964-02-29").isLeapYear
res19: Boolean = true
scala> LocalDate.parse("-3-02-29").toString
java.time.format.DateTimeParseException: Text '-3-02-29' could not be parsed at index 1
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDate.parse(LocalDate.java:428)
at java.base/java.time.LocalDate.parse(LocalDate.java:413)
... 36 elided
This shows that the calculation of leap years for BC years in java.time.LocalDate is wrong, because it doesn't take in account the offset by 1 caused by starting BC dates in year 0. Meaning that some invalid dates are possible, such as 29 Feb 5BC (29 Feb -0004 using the ISO representation) and some possible dates such as 29 Feb 4BC (29 Feb -0003 using the ISO representation) are not.
Proposed Solution: Make Date creation from LocalDate return an Option[Date] or construct the Date using Date.unsafe so that we can return invalid dates, which might be ok, given that the user of the library chose to use LocalDate which allows such representations.