1

I don't understand the reason why Jackson library is parsing wrong dates before 1912. I suppose the problem is the java.util.Date conversion, because the problem persists with Gson.

This is my code:

ObjectMapper mapper = new ObjectMapper();
String tmp = "{\"date\":\"1911-01-01T00:00:00+00:00\"}";
        
Response resp = mapper.readValue(tmp, Response.class);
System.out.println("Date->"+resp.date);

date is a field of type java.util.Date

As you can see, the input is: 1911-01-01T00:00:00+00:00

And the output is: Sun Jan 01 00:09:21 CET 1911 (I don't understand why that time is set)

But If I set this input: 1912-01-01T00:00:00+00:00

The ouput is correct: Mon Jan 01 00:00:00 CET 1912

Only happens with dates before 1912.

Jdk v1.8.0_101

Thanks.

Luisao
  • 455
  • 2
  • 9
  • 20
  • 2
    I'm not going to take time to investigate this, because as Basil Bourque's answer says you ought to switch to the java.time package not use the legacy java.util.Date class — but - _"I suppose the problem is the java.util.Date conversion"_ — as a general rule you should not start by assuming an error is in a well established library or package; it's nearly always a misunderstanding or error by the user of the package. Don't blame the package until you've thoroughly investigated your own code. 1912 is a significant date in the Minguo calendar and the end of the Meiji era so that could factor in. – Stephen P Jan 12 '21 at 17:56
  • Which is your default time zone? Europe/Madrid? Europe/Paris? Something else? – Ole V.V. Jan 12 '21 at 19:02
  • The output is correct. There have been some weird timezone changes in the past. I know there is an existing Stack Overflow question which covers this… – VGR Jan 12 '21 at 20:00
  • 2
    Possibly related: https://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result – VGR Jan 12 '21 at 20:07

2 Answers2

6

java.time

Never use the legacy class Date. Do not waste your time trying to understand the awful mess that is Date and Calendar.

Use only the modern java.time classes. Later versions of Jackson support java.time.

OffsetDateTime odt = OffsetDateTime.parse( "1911-01-01T00:00:00+00:00" ) ;

When asked to produce text representing its value, that OffsetDateTime generates:

odt.toString(): 1911-01-01T00:00Z

The Z on the end means an offset of zero hours-minutes-seconds from UTC, and is pronounced “Zulu”.


For an explanation as to what happened with your code using the legacy classes, see the excellent Answer by Ole V.V. But notice that using the properly-designed classes in java.time avoids the underlying issue: Applying a time zone where none was called for.

A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region. Your input carries an offset (of zero), with no indication of time zone. So no need to involve a time zone in processing your input.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
4

The good answer with the good solution has been posted by Basil Bourque. Here’s the answer explaining the reason for what you observed.

Europe/Paris time zone was at offset +00:09:21 from when a standard time was defined until March 11, 1911. I believe that some French possessions in Northern Africa (Algeria, Tunisia) followed suit. So if your default time zone falls within one of those places, then VGR is correct in the comment that your output is correct.

Nit-picking: Only the time zone abbreviation is debatable. According to the link below it should be PMT (supposedly for Paris Mean Time), not CET (supposedly for Central European Time). I don’t think the now outdated Date class ever had ambitions of giving correct historical time zone abbreviations though. It probably just gives CET because these days Paris uses Central European Time.

Once upon a time every capital and also many other metropols had their time defined by their mean solar time rather than a whole number of hours from some standard time reference (the role that GMT later acquired and still later UTC). So an offset of +00:09:21 was nothing special back then.

    ZonedDateTime dateTimeInFrance = OffsetDateTime.parse("1911-01-01T00:00:00+00:00")
            .atZoneSameInstant(ZoneId.of("Europe/Paris"));
    System.out.println(dateTimeInFrance);

Output:

1911-01-01T00:09:21+00:09:21[Europe/Paris]

Near-duplicate: Convert a timestamp before year 1900 in java.

Further link: Time Changes in Paris Over the Years

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161