Calendar to Date conversion for dates before 15 Oct 1582. Gregorian to Julian calendar switch

我与影子孤独终老i 提交于 2019-12-01 09:15:32

Method newXMLGregorianCalendar(s) must be feeded with a string in format "yyyy-MM-dd", that is using TWO digits for the day of month. But you have defined the strings "1582-10-4" and "1582-10-5" (instead of "1582-10-04" and "1582-10-05").

I have tested the replacement, and it works.

Remember that XMLGregorianCalendar is very strict and also uses the proleptic gregorian calendar according to the standard convention in ISO-8601. That means, it uses the gregorian leap year rules even before 1582. This explains your statement "Not coherent with calendar. Conversion to julian date?". For example:

The pope had removed 10 days following the date 1582-10-04 (in old julian calendar), so after this the date 1582-10-15 immediately followed in new gregorian calendar. In the proleptic gregorian calendar the date 1582-10-14 is well defined and corresponds to one day before 1582-10-15, hence the (historic julian) date 1582-10-04.

UPDATE AFTER EDIT OF OP:

The simple answer to your question "What determines whether or not we are using the proleptic gregorian calendar?" is: You decide.

In detail: If you use XMLGregorianCalendar then you use the proleptic gregorian calendar.

If you use java.util.GregorianCalendar then you have choosen the date 1582-10-15 as the first day of gregorian calendar by default. All former days are considered as being in julian calendar. You can override the default switch date however. For this to make work you just call the method setGregorianChange(Date) with an appropriate argument. An argument of new Date(Long.MIN_VALUE) sets the proleptic gregorian calendar while an argument of new Date(Long.MAX_VALUE) sets the proleptic julian calendar.

It is also important to note that

a) most countries did not switch to gregorian calendar in 1582-10-15 (only major catholic countries),

b) historical dates are further determined by other factors like different start of year (which makes the whole julian-gregorian-calendar-implementation in JDK completely insufficient - currently there is no library which gives support).

UPDATE AFTER EDIT-2:

The output proleptic [DAY_OF_MONTH [5], MONTH [9], YEAR [1582] is as expected and conserves the input as defined in proleptic gregorian calendar (10 days before 1582-10-15 applying the gregorian leap year rules backwards).

The output prolepticDate [Tue Sep 25 00:24:07 CET 1582] is a completely different story. But it is understandable if you remember that you really called the method toString() on java.util.Date. This method internally instantiates a new gregorian calendar object with the default switch of 1582-10-15. A Date-object has no idea (and no internal state) about setting the date for gregorian change, so its toString()-method just applies the default. Finally the proleptic calendar object is just recalculated/reformatted to a julian calendar representation in the specific format of Date.toString(). That is: 1582-09-25 (ten days before the switch).

UPDATE because of comment of @VGR:

My test verifies that for example for the proleptic date 1582-10-05 both XMLGregorianCalendar and a specialized construction of a new GregorianCalendar yield the same time in millis since unix-epoch, see here:

String s = "1582-10-05";
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
GregorianCalendar xml = datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar();

GregorianCalendar proleptic = new GregorianCalendar();
proleptic.clear(); // very important for proper comparison to reset time part to zero
proleptic.setGregorianChange(new Date(Long.MIN_VALUE));
proleptic.set(Calendar.DAY_OF_MONTH, 5);
proleptic.set(Calendar.MONTH, Calendar.OCTOBER);
proleptic.set(Calendar.YEAR, 1582);

boolean isEqual = (xml.getTimeInMillis() == proleptic.getTimeInMillis());

System.out.println("XML-millisSinceEpoch: " + xml.getTimeInMillis());
System.out.println("Proleptic-millisSinceEpoch: " + proleptic.getTimeInMillis());
System.out.println("XML==Proleptic (1582-10-05): " + isEqual);
System.out.println(
    "proleptic [DAY_OF_MONTH [" + proleptic.get(Calendar.DAY_OF_MONTH) + "], MONTH ["
    + proleptic.get(Calendar.MONTH) + "], YEAR [" + proleptic.get(Calendar.YEAR) + "]"
);
System.out.println("Date.toString() [" + proleptic.getTime() + "]");

The output:

XML-millisSinceEpoch: -12220160400000
Proleptic-millisSinceEpoch: -12220160400000
XML==Proleptic (1582-10-05): true
proleptic [DAY_OF_MONTH [5], MONTH [9], YEAR [1582]
Date.toString() [Tue Sep 25 00:00:00 CET 1582]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!