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

Java日期解析异常求助:IntelliJ运行报错但在线编译器正常

IntelliJ中DateTimeParseException异常排查与修复

在IntelliJ IDE中运行Java代码时抛出java.time.format.DateTimeParseException,提示文本‘December 05, 2020 at 10:00:00 AM PDT’无法在索引17处解析,但相同代码在在线Java编译器中可正常运行。

原代码

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;


public class MyClass {
    public static void main(String args[]) {
      String slot = "December 05, 2020 at 10:00:00 AM PDT";
      String locale = "en-US";
      String timezone = "America/Los_Angeles";
      long epoch = convertDateToLong(slot, locale, timezone);
      System.out.println(epoch);
    }
    
    private static long convertDateToLong (String dateTimeString, String locale, String timezone) {
        ZoneId zoneId = ZoneId.of(timezone);
        String offsetId = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of(timezone)).getOffset().toString();
        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withZone(zoneId).withLocale(Locale.forLanguageTag(locale));
        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, formatter);
        long epoch = localDateTime.toEpochSecond(ZoneOffset.of(offsetId));
        return epoch * 1000;
    }
}

问题根源

  • 本地化格式的环境差异:FormatStyle.LONG生成的格式规则依赖JDK版本和运行环境的本地化配置。在线编译器和IntelliJ的JDK版本或默认Locale配置不同,导致格式串不匹配目标字符串中的at关键字(索引17正是at的位置),触发解析失败。
  • 偏移量处理错误:通过Instant.now()获取当前时区偏移量去转换历史时间是错误的——历史时间(2020年12月)的时区偏移可能和当前不同(比如夏令时切换),会导致时间转换结果失真。

修复方案

使用自定义格式串替代本地化格式,明确解析规则,同时优化时区处理逻辑:

import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class MyClass {
    public static void main(String args[]) {
        String slot = "December 05, 2020 at 10:00:00 AM PDT";
        String locale = "en-US";
        String timezone = "America/Los_Angeles";
        long epoch = convertDateToLong(slot, locale, timezone);
        System.out.println(epoch);
    }

    private static long convertDateToLong(String dateTimeString, String locale, String timezone) {
        // 自定义匹配目标字符串的格式规则,'at'用单引号标记为固定文本
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy 'at' hh:mm:ss a zzz", Locale.forLanguageTag(locale));
        // 直接解析为带时区的ZonedDateTime,自动处理时区信息
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeString, formatter);
        // 直接转换为毫秒级时间戳
        return zonedDateTime.toInstant().toEpochMilli();
    }
}

优化说明

  • 自定义格式串完全匹配目标文本结构,不受环境本地化配置影响
  • 直接解析为ZonedDateTime,无需手动计算偏移量,避免夏令时等场景下的错误
  • 使用toInstant().toEpochMilli()直接获取毫秒时间戳,省去手动乘1000的冗余操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:55:11