You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java日期转换异常:Europe/Vienna时区1980-04-06无00:00时刻

日期转换小时偏移问题:00:00变01:00/23:00的原因解析

问题现象

两段日期转换代码均出现时间偏移:

  1. 使用SimpleDateFormat的示例:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", java.util.Locale.GERMAN);
String dateInString = "06-04-1980";
Date date = formatter.parse(dateInString);
  • 预期结果:Sun Apr 06 00:00:00 CEST 1980
  • 实际结果:Sun Apr 06 01:00:00 CEST 1980
  1. 使用Java 8+日期API的示例:
Date date = Date.from(LocalDate.of(1980, 4, 6).atStartOfDay(ZoneId.systemDefault()).toInstant());

同样出现00:00偏移为01:00的问题。

根因分析

最初怀疑是Java 11升级到Java 17导致,但实际核心原因是时区从Europe/Berlin切换为Europe/Vienna:

  • 1980年4月6日,奥地利(Europe/Vienna时区)启用夏令时,切换时刻为00:00——该时区当天不存在00:00这个时间点,Java会自动将时间调整到下一个有效时刻(01:00)。
  • 1893年3月31日之前的日期,Europe/Vienna时区的本地“当日起始时间”对应UTC的前一天23:00,因此转换后Calendar.HOUR_OF_DAY显示为23;而Europe/Berlin时区无此偏移,始终显示为00。

可复现验证代码

以下代码可遍历并输出所有Europe/Vienna时区中存在时间偏移的日期:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
for (LocalDate date = LocalDate.of(1500, 4, 1); 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");

内容的提问来源于stack exchange,提问作者anm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 02:24:22