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
相关产品推荐
相关产品推荐

