我在200年左右将Date
转换为LocalDate
时得到的结果不一致。使用以下代码进行转换:
private LocalDate toLocalDate(Date localDate)
{
return LocalDateTime.ofInstant(localDate.toInstant(), ZoneId.systemDefault()).toLocalDate();
}
我的ZoneId.systemDefault()
是Africa/Harare
,与测试中使用的CAT
相匹配。我运行的测试用例是
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)));
我的预期输出是
0200-01-01
0201-01-01
0200-12-31
或者,如果不是这样,至少始终不正确的值。实际结果是
0199-12-31
0201-01-01
0200-12-31
所以似乎第一个稍微回滚,可能是两个小时对应CAT
时区?但为什么这只发生在一个案例上呢?对2000年进行相同的实验不会产生相同的错误。
答案 0 :(得分:6)
java.util.Date
使用日历系统,该系统在1582年在Julian calendar system和Gregorian calendar system之间切换,跳过10天。因此,1582年或之前的日期将出现差异 - 但差异的大小将随时间变化 - 平均每400年3天。碰巧在200到400之间,你不看到这个,因为这与差异为0时相对应。
这是一个简短但完整的程序来演示问题:
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);
}
}
我机器上的输出:
0199-12-31T22:00:00Z
Tue Jan 01 22:00:00 GMT 200
这一点很复杂,因为您的初始代码中假设CAT和非洲/哈拉雷是相同的(在那个时间点,非洲/哈拉雷被认为有+02:10的偏移)和错误的一天你的字符串中的名字 - 但它是Java中导致此问题的错误。
我建议您使用java.time.format
类执行所有解析 - 然后我希望您不会出现这种不一致。