Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Date vs Gregorian Calendar / 48h difference? [duplicate]

Tags:

java

calendar

I had a curious situation at work, where an application sent us XML containing the value "0001-01-01", which was parsed into an instance of XmlGregorianCalendar. I then realized, the value magically converted into "0001-01-03", the exact amount of 2 days was added.

This happened during the conversion from GregorianCalendar to Date, which I reproduced as followed:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class Test {

    public static void main(String[] args) throws ParseException, DatatypeConfigurationException {
        final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        GregorianCalendar gregCalendar = new GregorianCalendar();
        gregCalendar.setTime(dateFormat.parse("0001-01-01"));
        XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregCalendar);

        System.out.println("calendar: " + calendar);
        System.out.println("date: " + calendar.toGregorianCalendar().getTime());
    }
}

Sample output:

calendar: 0001-01-01T00:00:00.000Z
date: Mon Jan 03 00:00:00 GMT 1

The milliseconds differ by the exact amount of 172800000. Does anybody know why?

like image 285
John Doe Avatar asked Aug 22 '17 15:08

John Doe


1 Answers

Cute isn't it? The Java GregorianCalendar is not a proleptic Gregorian Calendar (despite its misleading name) but a composite calendar consisting of a Julian beginning and Gregorian end. (You can even set the cutover date yourself.)

In the Gregorian Calendar, January 1, 0001 is a Monday.

In the Julian Calendar, January 1, 0001 is a Saturday.

And there, my friends, is the difference of two days.

References:

https://www.timeanddate.com/calendar/?year=1&country=22 https://www.timeanddate.com/calendar/?year=1&country=23 https://en.wikipedia.org/wiki/Adoption_of_the_Gregorian_calendar https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html

See SetGregorianChange in the final link in particular.

like image 161
Bathsheba Avatar answered Sep 22 '22 18:09

Bathsheba