Java – Convert date to localdate and return strange results around 200ad
When I converted dates to local dates in about 200 years, I got inconsistent results Use the following code for conversion:
private LocalDate toLocalDate(Date localDate) { return LocalDateTime.ofInstant(localDate.toInstant(),ZoneId.systemDefault()).toLocalDate(); }
My zoneid Systemdefault () is Africa / Harare, which matches the cat used in the test The test cases I run are
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 output is
0200-01-01 0201-01-01 0200-12-31
Or, if not, at least always incorrect values The actual result is
0199-12-31 0201-01-01 0200-12-31
So it seems that the first one to roll back slightly may be the cat time zone corresponding to two hours? But why does this only happen in one case? The same experiment in 2000 will not produce the same error
Solution
Stephen provided an explanation in his comments Basically, Java util. Date uses the calendar system, which switches between the Julian calendar system and the Gregorian calendar system in 1582, skipping 10 days As a result, there will be differences in dates from or before 1582 - but the magnitude of the differences will change over time - an average of 3 days per 400 years It happens that between 200 and 400 AD, you don't see this because it corresponds to the difference of 0
This is a short but complete program to demonstrate this 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
This is very complicated. Your initial code assumes that cat and Africa / Harare are the same (at that time, Africa / Harare is considered to have an offset of 02:10) and the wrong date name in your string - but this is an error that causes this problem in Java
I suggest you use Java time. The format class performs all the parsing - then I hope you don't get this inconsistency