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

将特定格式日期字符串转为Joda DateTime/Java Date时遇格式异常求助

日期字符串转Joda DateTime/Java Date失败的问题解决与最优方案

一、错误原因分析

1. Joda DateTime的问题

你的原Joda模式 "EEE MMM dd yyyy HH:mm:ss 'GMT'Z" 逻辑本身没问题,但漏掉了指定英文Locale。如果系统默认Locale不是英文,Joda无法解析Thu、May这类英文星期和月份缩写,直接就会抛出格式无效异常。另外要确保arrayHorarios里的日期字符串格式和模式完全匹配,没有多余空格或大小写偏差。

2. Java SimpleDateFormat的问题

你后来用的模式 "EEE MMM dd yyyy HH:mm:ss z" 里的z是用来匹配时区名称(比如GMT、CET),但你的日期字符串是GMT+0200,属于时区偏移量,应该用Z来匹配+0200部分,同时保留'GMT'字面量。而且同样需要指定Locale.ENGLISH,否则英文缩写解析会失败。

二、修复后的代码示例

1. Joda DateTime修复版

String pattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z";
// 强制指定英文Locale,避免系统Locale干扰
DateTimeFormatter formatter = DateTimeFormat.forPattern(pattern).withLocale(Locale.ENGLISH);
List<DateTime> dateTimeList = new ArrayList<>();
for (String horario : arrayHorarios) {
    DateTime dateTime = formatter.withOffsetParsed().parseDateTime(horario);
    dateTimeList.add(dateTime);
    // 如果需要转为Java Date
    Date javaDate = dateTime.toDate();
}

2. Java SimpleDateFormat修复版

ObjectMapper mapper = new ObjectMapper();
String[] arrayHorarios = mapper.readValue(horariosSave, String[].class);
// 修正模式并指定英文Locale
DateFormat df = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.ENGLISH);
List<Date> hor = new ArrayList<>();
try {
    for (int i = 0; i < arrayHorarios.length; i++) {
        System.out.println("Horario nº:"+i);
        System.out.println("String = "+arrayHorarios[i]);
        Date date = df.parse(arrayHorarios[i]);
        System.out.println("Date = " + df.format(date));
        hor.add(date);
    }
    System.out.println("Clases guardadas:"+hor.size());
} catch (Exception e) {
    e.printStackTrace();
}

三、最简单的实现方案(推荐Java 8+)

Joda-Time已经被官方标记为过时,更推荐使用Java 8引入的java.time(JSR-310)API——它线程安全、功能完善,且JDBC 4.2+版本原生支持直接存入数据库,无需转成老旧的Date类。

代码示例

ObjectMapper mapper = new ObjectMapper();
String[] arrayHorarios = mapper.readValue(horariosSave, String[].class);
// 定义格式器并指定英文Locale
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.ENGLISH);
List<OffsetDateTime> offsetDateTimeList = new ArrayList<>(); // 推荐用这个替代Date
List<Date> dateList = new ArrayList<>(); // 仅当必须兼容旧API时使用

for (String horario : arrayHorarios) {
    // 解析为带时区偏移的日期时间对象
    OffsetDateTime offsetDateTime = OffsetDateTime.parse(horario, formatter);
    offsetDateTimeList.add(offsetDateTime);
    
    // 如需转为Java Date(仅兼容旧代码场景)
    Date javaDate = Date.from(offsetDateTime.toInstant());
    dateList.add(javaDate);
}

// 存数据库时,直接用OffsetDateTime即可(JDBC 4.2+支持)
// 示例:preparedStatement.setObject(1, offsetDateTime);

关键注意点

  • 必须指定Locale.ENGLISH:因为日期字符串中的星期、月份是英文缩写,避免系统默认Locale(如中文)导致解析失败。
  • 区分时区名称与偏移量:你的字符串是GMT+0200属于偏移量,要用Z匹配,而不是匹配时区名称的z。
  • 优先用java.time:Joda-Time已停止维护,java.time是官方推荐的日期时间API,功能更强大且无历史遗留问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:00:18