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

解析两种格式时间字符串为LocalDateTime遇异常,求解决方案

解决方案

1. 自定义兼容双格式的DateTimeFormatter

核心思路是构建一个同时支持可变长度小数秒和可选时区偏移的格式化器,先解析为能处理时区的OffsetDateTime,再提取出LocalDateTime:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class TimeParser {
    public static void main(String[] args) {
        // 构建兼容两种格式的格式化器
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
                // 可选1-7位小数秒,自动适配长度
                .optionalStart()
                .appendFraction(ChronoField.NANO_OF_SECOND, 1, 7, true)
                .optionalEnd()
                // 可选时区偏移(如+03:00)
                .optionalStart()
                .appendPattern("XXX")
                .optionalEnd()
                .toFormatter();

        // 解析带时区的7位小数时间
        String timeWithZone = "2023-02-22T09:47:00.5371934+03:00";
        LocalDateTime ldt1 = OffsetDateTime.parse(timeWithZone, formatter).toLocalDateTime();
        System.out.println(ldt1); // 输出:2023-02-22T09:47:00.5371934

        // 解析无时区的3位小数时间
        String timeWithoutZone = "2023-02-22T09:47:00.537";
        LocalDateTime ldt2 = OffsetDateTime.parse(timeWithoutZone, formatter).toLocalDateTime();
        System.out.println(ldt2); // 输出:2023-02-22T09:47:00.537
    }
}

2. 原方案失效原因

  • ISO_ZONED_DATE_TIME强制要求字符串包含时区信息,但第二个时间字符串无时区,直接解析会报错;
  • 它对小数秒的长度兼容性差,无法自动适配3位与7位的差异。

3. 简化替代方案(不推荐)

如果不想自定义格式化器,可通过字符串预处理统一格式:

public static LocalDateTime parseTime(String timeStr) {
    // 给无时区的字符串添加默认时区
    if (!timeStr.contains("+")) {
        timeStr += "+00:00";
    }
    // 补全小数秒到7位(不足补0)
    int dotIndex = timeStr.indexOf('.');
    int zoneIndex = timeStr.indexOf('+');
    if (dotIndex != -1 && zoneIndex - dotIndex - 1 < 7) {
        String secPart = timeStr.substring(dotIndex, zoneIndex);
        while (secPart.length() < 8) {
            secPart += "0";
        }
        timeStr = timeStr.substring(0, dotIndex) + secPart + timeStr.substring(zoneIndex);
    }
    return OffsetDateTime.parse(timeStr).toLocalDateTime();
}

这种硬编码方式易出边界问题,优先推荐自定义格式化器方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:11:09