> Also covers: [8249280](https://bugs.openjdk.org/browse/JDK-8249280)
> 
> I will first give a quick summary of the problem.
> Put simply, the `LocalDate` form of the `java.sql.Date` is derived using the 
> `getYear` method of `java.util.Date`. This in turn returns the year of the 
> normalised internal calendar.
> However, the internal calendar `getYear` has an extra layer of complexity.
> The calendar has an additional era field, which captures BC/AD.
> `getYear` therefore just returns the year _of that era_.
> For example, the year 6BC and the year 6AD both return `getYear` as 6.
> 
> **This means that for BC dates, our `LocalDate` conversion loses the sign of 
> the year.**
> 
> This leads to additional problems down the line, as the year 1BC is for 
> calculations sake is considered to be year 0 (and 2BC us considered year -1 
> and so on). As a result, the various leap year calculations are WRONG for 
> these years, causing year format validation failures in situations like 
> marshalling/unmarshalling the dates with a DB.
> 
> There are two seemingly obvious fixes here, however I will attempt to explain 
> why I did not proceed with them.
> 
> Firstly, it seems sensible is to derive the `LocalDate` from an `Instant` 
> created from the millisecond representation of the `Date`. After all, why we 
> are having to use the deprecated `getYear`, `getMonth` and `getDay` methods 
> anyway?
> The answer lies in [8061577](https://bugs.openjdk.org/browse/JDK-8061577).
> The underlying millisecond representation between `java.time.Instant` and 
> `java.util.Date` is fundamentally different. Read that ticket for a greater 
> explanation.
> Ultimately though, it means that the for older dates, the only real way to 
> bridge between the two calendar systems is to use these year/month/day 
> methods.
> 
> This is where the second possible solution appears.
> The underlying calendar representation that `java.util.Date` uses actually 
> does have a year method which gives you the correctly signed year, that being 
> `getNormalizedYear`.
> In fact, `java.util.Date` uses the setter counterpart `setNormalizedYear` is 
> its `setYear` method.
> Given this, it seems natural that `getYear` should similarly call 
> `getNormalizedYear`.
> I think this would be my ideal solution, however I recognise that `get`Year 
> only returning a positive year is very long standing behaviour. Given how 
> widely spread `java.util.Date` is, I felt it was perhaps better not to rock 
> the boat too much.
> 
> I have therefore taken the decision to add an equivalent `getNormalizedYear` 
> method to `java.util.Da...

Sholto has updated the pull request incrementally with one additional commit 
since the last revision:

  8272194: introduce faster code path for LocalDate/LocalDateTime conversion

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/31808/files
  - new: https://git.openjdk.org/jdk/pull/31808/files/97c5704d..745c717c

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=31808&range=02
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=31808&range=01-02

  Stats: 28 lines in 2 files changed: 28 ins; 0 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/31808.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/31808/head:pull/31808

PR: https://git.openjdk.org/jdk/pull/31808

Reply via email to