I have legacy code that uses java.util.Date creating an ancient date (30 Nov 0002). I\'m trying to update what code I can, but that\'s necessitating converting between Date
The discrepancy resides in how the implementations of Date
and Instant
interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.
The GregorianCalendar
implementation has a special note:
Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.
Well, yes, technically speaking. But for this issue, we don't quite encounter this.
cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);
This yields a date, as expected, of October 4, 1582.
cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);
This yields a date, of October 15, 1582.
WHAT MAGIC IS THIS, BATMAN?
Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.
However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),
From Wikipedia on 1582
When we examine October 4, 1582, the following happens:
Date: 1582-Oct-04 00:00:00
Instant: 1582-10-14T00:00:00Z
There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.
The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).
SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.
Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.
If you are displaying historical event dates, you will be better off using a Date
or JulianCalendar
DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.