Converting a date to LocalDate returning strange results around 200AD

I get inconsistent results when converting Date to LocalDate s for about 200 years. Using the following code to convert:

  private LocalDate toLocalDate(Date localDate) { return LocalDateTime.ofInstant(localDate.toInstant(), ZoneId.systemDefault()).toLocalDate(); } 

My ZoneId.systemDefault() is Africa/Harare , which corresponds to the CAT used in the test. The run I run

 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); String dateString = "Tue Jan 01 00:00:00 CAT 200"; String dateString2 = "Tue Jan 01 00:00:00 CAT 201"; String dateString3 = "Wed Dec 31 00:00:00 CAT 200"; System.out.println(toLocalDate(simpleDateFormat.parse(dateString))); System.out.println(toLocalDate(simpleDateFormat.parse(dateString2))); System.out.println(toLocalDate(simpleDateFormat.parse(dateString3))); 

My expected result for this would be

 0200-01-01 0201-01-01 0200-12-31 

Or, if not this, at least the invariably incorrect values. Actual Results:

 0199-12-31 0201-01-01 0200-12-31 

So, it seems that the first one is a bit of a rollback, perhaps two hours, corresponding to the CAT time zone? But why does this happen in only one case? Performing the same experiment since 2000 does not lead to the same error.

+7
java date java-8 java-time
source share
1 answer

Stephen provided an explanation in a comment. Basically, java.util.Date uses a calendar system that cuts through the Julian calendar system and the Gregorian calendar system in 1582, skipping 10 days. Thus, dates in 1582 or earlier will have discrepancies - but the size of the discrepancy will change over time - on average by 3 days every 400 years. It so happened that from 200 to 400AD you do not see this, because it corresponds to when the mismatch is 0.

Here's a short but complete program to demonstrate the problem:

 import java.time.*; import java.util.*; public class Test { public static void main(String[] args) throws Exception { // Value obtained with Noda Time: should be 0199-12-31T22:00:00Z. long millis = -55855792800000L; Instant instant = Instant.ofEpochMilli(millis); Date date = new Date(millis); System.out.println(instant); System.out.println(date); } } 

Output on my machine:

 0199-12-31T22:00:00Z Tue Jan 01 22:00:00 GMT 200 

All this is complicated by problems in your source code, assuming that CAT and Africa / Harare are the same (at that time Africa / Harare is considered offset +02: 10) and the wrong day the names in your lines - but this is a bug in Java that causes the problem here .

I suggest you do all your parsing using the java.time.format classes - then I hope you don't get this inconsistency.

+6
source share

All Articles