Given that Gregorian Calendar start date is 15 Oct 1582, please consider the following tests and please help me understanding what happens:
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import org.junit.Test;
@Test
public void gregorianToDateConversion() {
GregorianCalendar calendar = null;
Date date = null;
calendar = new GregorianCalendar(1582, 9, 04);
date = calendar.getTime();
System.out.println("new GregorianCalendar(1582, 9, 4) -> calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date:" + date);
calendar = new GregorianCalendar(1582, 9, 05);
date = calendar.getTime();
System.out.println("\nnew GregorianCalendar(1582, 9, 5) -> calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date:" + date);
calendar = new GregorianCalendar(1582, 9, 14);
date = calendar.getTime();
System.out.println("\nnew GregorianCalendar(1582, 9, 14) -> calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date:" + date);
calendar = new GregorianCalendar(1582, 9, 15);
date = calendar.getTime();
System.out.println("\nnew GregorianCalendar(1582, 9, 15) -> calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date:" + date);
String dateToParse = null;
dateToParse = "1582-10-04";
System.out.println("\nString to parse: " + dateToParse);
calendar = parseDateTime(dateToParse);
if(calendar != null) {
date = calendar.getTime();
System.out.println("datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() -> \n calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date: " + date);
}
dateToParse = "1582-10-05";
System.out.println("\nString to parse: " + dateToParse);
calendar = parseDateTime(dateToParse);
if(calendar != null) {
date = calendar.getTime();
System.out.println("datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() -> \n calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date: " + date);
}
dateToParse = "1582-10-14";
System.out.println("\nString to parse: " + dateToParse);
calendar = parseDateTime(dateToParse);
if(calendar != null) {
date = calendar.getTime();
System.out.println("datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() -> \n calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date: " + date);
}
dateToParse = "1582-10-15";
System.out.println("\nString to parse: " + dateToParse);
calendar = parseDateTime(dateToParse);
if(calendar != null) {
date = calendar.getTime();
System.out.println("datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() -> \n calendar[DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("calendar.getTime() -> Date: " + date);
}
}
private GregorianCalendar parseDateTime(String s) {
DatatypeFactory datatypeFactory = null;
try {
datatypeFactory = DatatypeFactory.newInstance();
return datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
The results are the following:
new GregorianCalendar(1582, 9, 4) -> calendar[DAY_OF_MONTH [4], MONTH [9], YEAR [1582]] **OK**
calendar.getTime() -> Date:Thu Oct 04 00:00:00 CET 1582 **OK**
new GregorianCalendar(1582, 9, 5) -> calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]] **+ 10 days ??**
calendar.getTime() -> Date:Fri Oct 15 00:00:00 CET 1582 **coherent with calendar**
new GregorianCalendar(1582, 9, 14) -> calendar[DAY_OF_MONTH [24], MONTH [9], YEAR [1582]] **+ 10 days ??**
calendar.getTime() -> Date:Sun Oct 24 00:00:00 CET 1582 **coherent with calendar**
new GregorianCalendar(1582, 9, 15) -> calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]] **OK**
calendar.getTime() -> Date:Fri Oct 15 00:00:00 CET 1582 **OK**
String to parse: 1582-10-04
datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() ->
calendar[DAY_OF_MONTH [4], MONTH [9], YEAR [1582]]
calendar.getTime() -> Date: Mon Sep 24 00:00:00 CET 1582 **Not coherent with calendar. Conversion to julian date?**
String to parse: 1582-10-05
datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() ->
calendar[DAY_OF_MONTH [5], MONTH [9], YEAR [1582]]
calendar.getTime() -> Date: Tue Sep 25 00:00:00 CET 1582 **Not coherent with calendar. Conversion to julian date?**
String to parse: 1582-10-14
datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() ->
calendar[DAY_OF_MONTH [14], MONTH [9], YEAR [1582]] **OK**
calendar.getTime() -> Date: Thu Oct 04 00:00:00 CET 1582 **Not coherent with calendar. Conversion to julian date?**
String to parse: 1582-10-15
datatypeFactory.newXMLGregorianCalendar(s).toGregorianCalendar() ->
calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]] **OK**
calendar.getTime() -> Date: Fri Oct 15 00:00:00 CET 1582 **OK**
Could you clarify me what is happening? Thank you very much.
EDIT: Thank you, I've fixed my mistakes about the format of the date to parse: now all have the form yyyy-MM-gg and no exceptions are thrown anymore.
Now I try to clarify my dubts.
What determines whether or not we are using the proleptic gregorian calendar?
By summarizing:
java.util.GregorianCalendar represents a julian calendar for dates before 15 Oct 1582 and a gregorian calendar after this date. Is it right?
So, this justifies the behaviour in the new GregorianCalendar(...)...
If I do:
new GregorianCalendar(1582, 9, 4)
I have
calendar[DAY_OF_MONTH [4], MONTH [9], YEAR [1582]]
because 4 Oct 1582 exists in the julian calendar and the calendar I've created represents a julian date.
Converting this calendar to date, we have:
Date:Thu Oct 04 00:00:00 CET 1582, consistent with Calendar.
If I do:
new GregorianCalendar(1582, 9, 5)
I obtain
calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]]
because the day 5 of October neither exists in julian nor in gregorian calendar. So the GregorianCalendar constructor creates a date exactely 1 day after the 4 of October, that is the first day of the gregorian calendar, the 15 of October. The new date is then expressed in gregorian calendar system.
I'll have the same behaviour creating a new calendar passing dates from (1582, 9, 5) to (1582, 9, 14).
In the example above, the converted java.util.Date is again consistent with the Calendar
Date:Fri Oct 15 00:00:00 CET 1582
If I do:
new GregorianCalendar(1582, 9, 15)
I have
calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]]
because 15 of October exists in gregorian calendar and the new date is expressed in this system. The Calendar converted into Date is again consistent:
Date:Fri Oct 15 00:00:00 CET 1582
This means that the GregorianCalendar constructor assumes that I enter dates in the calendar system that is valid in the given epoch: in other words assumes that if I enter a date prior then or equal to 04 October I'm thinking the date according to the julian calendar and the date is expressed in this system, if I enter a date between 05 and 14 October it counts the number of days between the end date of julian calendar (04 october) and the date I entered and sums this days to the start date of gregorian calendar (15 October) and express the new date in gregorian system, and if I enter a date after or equal to 15 October it assumes that the date I entered is meant in gregorian calendar and the new date is expressed in this system.
Is all this correct?
This is not a proleptic behaviour, right? If the calendar was a proleptic gregorian calendar I would expect that initializing it with
new GregorianCalendar(1582, 9, 5)
I would obtain
calendar[DAY_OF_MONTH [5], MONTH [9], YEAR [1582]]
that is the 5 of October is set also if the date does not exists in the gregorian system and, being 10 days befor the first day of gregorian calendar, it would be equal to the julian date 25 september, if I'm not mistaken.
How can I decide to use the proleptic gregorian calendar or not?
Parsing a String and creating a new GregorianCalendar passing through the XmlGregorianCalendar, the behaviour seems to me different.
Parsing "1582-10-04" I obtain
calendar[DAY_OF_MONTH [4], MONTH [9], YEAR [1582]]
(same as the example above..) but a date
Date: Mon Sep 24 00:00:00 CET 1582
(Here we have a julian date, is it right? But in the example above (where the GregorianCalendar was created by its constructor) the Date was equal to the Calendar. Why now it is different?
Parsing the string "1582-10-05" we have
calendar[DAY_OF_MONTH [5], MONTH [9], YEAR [1582]]
(Now we have a Proleptic gregorian calendar, right?)
But again a different Date
Date: Tue Sep 25 00:00:00 CET 1582 (Julian Date? Why?)
Same behaviour parsing "1582-10-14"
calendar[DAY_OF_MONTH [14], MONTH [9], YEAR [1582]]
Date: Thu Oct 04 00:00:00 CET 1582
If we finally parse "1582-10-15", we come back in the Gregorian age ad all become consistent:
calendar[DAY_OF_MONTH [15], MONTH [9], YEAR [1582]]
Date: Fri Oct 15 00:00:00 CET 1582
Can you help me to understand all this behaviours?
Thank you very much.
EDIT 2:
Thank you for your answers, also if some doubt remains for me. I tried the following code:
GregorianCalendar proleptic = new GregorianCalendar();
proleptic.setGregorianChange(new Date(Long.MIN_VALUE));
proleptic.set(Calendar.DAY_OF_MONTH, 5);
proleptic.set(Calendar.MONTH, 9);
proleptic.set(Calendar.YEAR, 1582);
System.out.println("proleptic [DAY_OF_MONTH ["+proleptic.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+proleptic.get(Calendar.MONTH)+"], YEAR ["+proleptic.get(Calendar.YEAR)+"]");
Date prolepticDate = proleptic.getTime();
System.out.println("prolepticDate ["+prolepticDate+"]");
The output was:
proleptic [DAY_OF_MONTH [5], MONTH [9], YEAR [1582]
prolepticDate [Tue Sep 25 00:24:07 CET 1582]
Now I have the calendar with DAY_OF_MONTH consistent with what I've set, so I think this is a proleptic behaviour, right? But again I ask why the Date, obtained by the getTime() method, does not represent the same day, but 10 days before. Thanks again.
EDIT 3:
The question is for me a bit clearer, but not completely. I did not understand in detail by what logic the conversion from GregorianCalendar to Date is done and why a proleptic Gregorian Calendar and a traditional one, each constructed with the same parameters as DAY, MONTH and YEAR, not always represent the same instant of time. I did some further tests.
GregorianCalendar proleptic = null;
GregorianCalendar calendar = null;
Date date = null;
// ---- JULIAN PERIOD ----
proleptic = new GregorianCalendar();
proleptic.clear();
proleptic.setGregorianChange(new Date(Long.MIN_VALUE));
proleptic.set(Calendar.DAY_OF_MONTH, 5);
proleptic.set(Calendar.MONTH, Calendar.FEBRUARY);
proleptic.set(Calendar.YEAR, 1582);
System.out.println("proleptic_calendar_5Feb1582 [DAY_OF_MONTH ["+proleptic.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+proleptic.get(Calendar.MONTH)+"], YEAR ["+proleptic.get(Calendar.YEAR)+"]");
date = proleptic.getTime();
System.out.println("date_5Feb1582 from proleptic ["+date+"]");
calendar = new GregorianCalendar(1582, 1, 5);
date = calendar.getTime();
System.out.println("new GregorianCalendar(1582, 1, 5) -> [DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("new GregorianCalendar(1582, 1, 5) .getTime() -> Date:" + date);
System.out.println("proleptic_calendar_5Feb1582 in millis ["+proleptic.getTimeInMillis()+"], new GregorianCalendar(1582, 1, 5) in millis ["+calendar.getTimeInMillis()+"], millis are equal ["+ (proleptic.getTimeInMillis() == calendar.getTimeInMillis()) +"]");
//--------
System.out.println("\n");
// ---- transition period ----
proleptic = new GregorianCalendar();
proleptic.clear();
proleptic.setGregorianChange(new Date(Long.MIN_VALUE));
proleptic.set(Calendar.DAY_OF_MONTH, 8);
proleptic.set(Calendar.MONTH, Calendar.OCTOBER);
proleptic.set(Calendar.YEAR, 1582);
System.out.println("proleptic_calendar_8Oct1582 [DAY_OF_MONTH ["+proleptic.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+proleptic.get(Calendar.MONTH)+"], YEAR ["+proleptic.get(Calendar.YEAR)+"]");
date = proleptic.getTime();
System.out.println("date_5Oct1582 from proleptic ["+date+"]");
calendar = new GregorianCalendar(1582, 9, 8);
date = calendar.getTime();
System.out.println("new GregorianCalendar(1582, 9, 8) -> [DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("new GregorianCalendar(1582, 9, 8) .getTime() -> Date:" + date);
System.out.println("proleptic_calendar_8Oct1582 in millis ["+proleptic.getTimeInMillis()+"], new GregorianCalendar(1582, 9, 8) in millis ["+calendar.getTimeInMillis()+"], millis are equal ["+ (proleptic.getTimeInMillis() == calendar.getTimeInMillis()) +"]");
//--------
System.out.println("\n");
// ---- GREGORIAN PERIOD ----
proleptic = new GregorianCalendar();
proleptic.clear();
proleptic.setGregorianChange(new Date(Long.MIN_VALUE));
proleptic.set(Calendar.DAY_OF_MONTH, 5);
proleptic.set(Calendar.MONTH, Calendar.DECEMBER);
proleptic.set(Calendar.YEAR, 1582);
System.out.println("proleptic_calendar_5Dec1582 [DAY_OF_MONTH ["+proleptic.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+proleptic.get(Calendar.MONTH)+"], YEAR ["+proleptic.get(Calendar.YEAR)+"]");
date = proleptic.getTime();
System.out.println("date_5Dec1582 from proleptic ["+date+"]");
calendar = new GregorianCalendar(1582, 11, 5);
date = calendar.getTime();
System.out.println("new GregorianCalendar(1582, 11, 5) -> [DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]]");
System.out.println("new GregorianCalendar(1582, 11, 5) .getTime() -> Date:" + date);
System.out.println("proleptic_calendar_5Dec1582 in millis ["+proleptic.getTimeInMillis()+"], new GregorianCalendar(1582, 11, 5) in millis ["+calendar.getTimeInMillis()+"], millis are equal ["+ (proleptic.getTimeInMillis() == calendar.getTimeInMillis()) +"]");
//--------
The output was:
proleptic_calendar_5Feb1582 [DAY_OF_MONTH [5], MONTH [1], YEAR [1582]
date_5Feb1582 from proleptic [Fri Jan 26 00:00:00 CET 1582]
new GregorianCalendar(1582, 1, 5) -> [DAY_OF_MONTH [5], MONTH [1], YEAR [1582]]
new GregorianCalendar(1582, 1, 5) .getTime() -> Date:Mon Feb 05 00:00:00 CET 1582
proleptic_calendar_5Feb1582 in millis [-12241069200000], new GregorianCalendar(1582, 1, 5) in millis [-12240205200000], millis are equal [false]
proleptic_calendar_8Oct1582 [DAY_OF_MONTH [8], MONTH [9], YEAR [1582]
date_5Oct1582 from proleptic [Fri Sep 28 00:00:00 CET 1582]
new GregorianCalendar(1582, 9, 8) -> [DAY_OF_MONTH [18], MONTH [9], YEAR [1582]]
new GregorianCalendar(1582, 9, 8) .getTime() -> Date:Mon Oct 18 00:00:00 CET 1582
proleptic_calendar_8Oct1582 in millis [-12219901200000], new GregorianCalendar(1582, 9, 8) in millis [-12219037200000], millis are equal [false]
proleptic_calendar_5Dec1582 [DAY_OF_MONTH [5], MONTH [11], YEAR [1582]
date_5Dec1582 from proleptic [Sun Dec 05 00:00:00 CET 1582]
new GregorianCalendar(1582, 11, 5) -> [DAY_OF_MONTH [5], MONTH [11], YEAR [1582]]
new GregorianCalendar(1582, 11, 5) .getTime() -> Date:Sun Dec 05 00:00:00 CET 1582
proleptic_calendar_5Dec1582 in millis [-12214890000000], new GregorianCalendar(1582, 11, 5) in millis [-12214890000000], millis are equal [true]
The first test (5 Feb 1582) refers to a period belonging to the Julian calendar, the second (8 Oct 1582) belongs to the period of transition, the third (5 Dec 1582) to the Gregorian Calendar period. Then I think to notice the following things:
Julian Period
- the proleptic Gregorian Calendar seems to represent the desired date
- the obtained Date, as explained by @Meno Hochschild, is converted to a Julian date (-10 days)
- the traditional Gregorian Calendar also seems to represent the desired date...
- but the obtained Date is different from the previous one
- infact, the two Gregorian Calendar represent two different instant of time, see the millisecond values
transition period
- the proleptic Gregorian Calendar seems to represent the desired date
- the obtained Date, again, is converted to a Julian date (-10 days)
- the traditional Gregorian Calendar seems to be the effect of a conversion in Gregorian Calendar of a date (8 Oct) initially expressed in a proleptic Julian Calendar (8 Oct = 4 days more then Julian Calendar MAX DATE (4 Oct) = 3 days more then Gregorian Calendar MIN DATE = 15 + 3 = 18 Oct. (It is a supposition)
- this time the obtained Date seems to represent the same date of the above traditional Gregorian Calendar (without being converted to julian date, this time?)
- the two Gregorian Calendar again represent two different instant of time, see the millisecond values
Gregorian Period
- the proleptic Gregorian Calendar represent the desired date
- the obtained Date represent the same date
- the traditional Gregorian Calendar represent the desired date
- the obtained Date represent the same date
- the two Gregorian Calendar represents the same instant of time, same number of milliseconds
Could you help me to explain one by one all of these results?
Thanks.
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]
来源:https://stackoverflow.com/questions/23457470/calendar-to-date-conversion-for-dates-before-15-oct-1582-gregorian-to-julian-ca