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

Java 8与Java 11中Instant.toEpochMilli结果不一致问题求助

Java 8与Java 11中DateTimeFormatter解析带时区日期生成的时间戳不一致

问题详情

以下代码在Java 8和Java 11运行时,输出的epoch毫秒时间戳结果不一致:

String strDate = "2022-07-18 17:52:23 America/New_York";
DateTimeFormatter frmt  = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd HH:mm:ss VV")
    .parseDefaulting(ChronoField.HOUR_OF_DAY,0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR,0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE,0)
    .parseDefaulting(ChronoField.NANO_OF_SECOND,0)
    .parseDefaulting(ChronoField.OFFSET_SECONDS,0)
    .toFormatter();

TemporalAccessor temporal = frmt.parse(strDate);
System.out.println(Instant.from(temporal).toEpochMilli()); 

输出差异

  • Java 8:1658181143000(对应纽约时区的正确时间戳)
  • Java 11:1658166743000(错误,对应UTC时区的时间戳)

问题原因

问题出在parseDefaulting(ChronoField.OFFSET_SECONDS,0)这一行:

  • Java 8中,解析到VV(时区ID)时,会自动计算该时区对应的偏移量,并覆盖默认设置的OFFSET_SECONDS值;
  • Java 11调整了解析逻辑的优先级,显式设置的OFFSET_SECONDS默认值会优先生效,导致解析时忽略了从America/New_York时区ID获取的实际偏移量,强制使用UTC偏移(0秒)。

解决方案

移除parseDefaulting(ChronoField.OFFSET_SECONDS,0)这一行即可。通过VV模式解析出的时区ID已经包含该时区的正确偏移信息,无需额外设置默认偏移量。

修改后的代码:

String strDate = "2022-07-18 17:52:23 America/New_York";
DateTimeFormatter frmt  = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd HH:mm:ss VV")
    .parseDefaulting(ChronoField.HOUR_OF_DAY,0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR,0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE,0)
    .parseDefaulting(ChronoField.NANO_OF_SECOND,0)
    .toFormatter();

TemporalAccessor temporal = frmt.parse(strDate);
System.out.println(Instant.from(temporal).toEpochMilli()); 

验证结果

修改后,Java 8和Java 11均输出正确的纽约时区对应时间戳:1658181143000


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:44:54