我们面临以下问题:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", java.util.Locale.GERMAN);
String dateInString = "06-04-1980";
Date date = formatter.parse(dateInString);
之前:1980年欧洲中部时间4月6日星期日00:00:00
之后:1980年欧洲中部时间4月6日星期日01:00:00
另一个例子:
Date date = Date.from(LocalDate.of(1980, 4, 6).atStartOfDay(ZoneId.systemDefault()).toInstant());
面对同样的问题。
我们认为将java11更改为java17是问题所在,但事实并非如此。这是时区从欧洲/柏林更改为欧洲-维也纳。1980-04-06年,奥地利实行夏令时,时间改为00:00。所以这一天没有00:00。
可再现示例-将时区更改为"0";欧洲/柏林";结果在0小时内。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
for (LocalDate date = LocalDate.of(1500, 04, 01); date.isBefore(LocalDate.of(9999, 1, 1)); date = date.plusDays(1)) {
Date out = Date.from(date.atStartOfDay(ZoneId.of("Europe/Vienna")).toInstant());
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone(ZoneId.of("Europe/Vienna")));
cal.setTime(out);
if (cal.get(Calendar.HOUR_OF_DAY) > 0) {
System.out.println(date.format(formatter) + " > " + cal.get(Calendar.HOUR_OF_DAY));
}
}
System.out.println("done");
1893-03-31年之前的所有日期都有23小时的时区";欧洲/维也纳";,在";欧洲/柏林";也是0。
这不是一个真正的问题,这是时区的一个特殊之处"欧洲/维也纳";这在我们的系统中发生了变化。如果你遇到这个问题,请检查你的时区,也许它被其他属性更改了。
虽然德国的夏令时间(夏令时(从当天的02:00开始,但奥地利(欧洲/维也纳时区(已经在午夜开始,所以00:00时间并不存在,这就是为什么我们突然得到01:00的原因。这两个时区都打印为中欧夏令时间,因此缩写不允许我们区分。
我在以色列,所以为了模拟中欧的时区(使用Java 17(,我使用Java命令的-D
选项将[System]属性user.timezone设置为CET。然后我运行了以下代码:
/*
* import java.time.ZoneId;
* import java.time.ZonedDateTime;
* import java.util.Date;
*/
ZonedDateTime zdt = ZonedDateTime.of(1980, 4, 6, 0, 0, 0, 0, ZoneId.systemDefault());
System.out.println(Date.from(zdt.toInstant()));
我得到的结果是:
Sun Apr 06 00:00:00 CET 1980
这就是你想要的结果,对吗?