格式EEEE,MMMM d,YYYY h:mm:ss a z的分析异常

时间:2013-05-15 13:58:35

标签: java datetime datetime-format

我在尝试解析字符串值时遇到了解析器异常:

"Thursday, July 27, 2006 10:10:02 PM PST" 

格式化:

"EEEE, MMMM d, YYYY h:mm:ss a z"

这是程序样本:

DateTime.parse("Thursday, July 27, 2006 10:10:02 PM PDT", DateTimeFormat.forPattern("EEEE, MMMM d, yyyy h:mm:ss a z"));

这是错误消息:

Invalid format: "Thursday, July 27, 2006 10:10:02 PM PDT" is malformed at "PDT"

这是我的示例程序

String str = "Thursday, July 27, 2006 10:10:02 PM PDT"; 
DateTimeFormatter formatterDateTime = DateTimeFormat.forPattern("EEEE, MMMM d, YYYY h:mm:ss a z");
try{
    DateTime dt = DateTime.parse(str, formatterDateTime);
}catch(Exception ex)
{
    System.out.println(ex.getMessage());
}

4 个答案:

答案 0 :(得分:1)

来自JodaTime docs

  

区域名称:无法解析时区名称('z')。

但是SimpleDateFormat确实支持解析时区。

SimpleDateFormat format = new SimpleDateFormat("EEEE, MMMM dd, YYYY h:mm:ss aa zzz");
Date date = format.parse("Thursday, July 27, 2006 10:10:02 PM PST");

答案 1 :(得分:1)

正如marba所建议的那样,错误很可能是由Java 7使用Java 7特定模式引起的。

解析日期的代码如下所示:

SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy h:mm:ss aa zzz");
Date d = df.parse("Thursday, July 27, 2006 10:10:02 PM PST");

测试解析日期与提供的日期相同:

df.setTimeZone(TimeZone.getTimeZone("Pacific/Pitcairn"));
System.out.println(df.format(d));

打印:

Thursday, July 27, 2006 10:10:02 PM PST

有关更多模式,请参阅Javadoc

答案 2 :(得分:0)

您使用的是哪种语言环境?我认为您必须明确提供Locale.US作为SimpleDateFormat的第二个参数。

对于Joda-Time库,您可以使用以下代码调整区域设置:

DateTimeFormat.forPattern("EEEE, MMMM d, YYYY h:mm:ss a z").withLocale(Locale.US);

更新:刚刚找到this related SO question,您似乎需要使用SimpleDateFormat。 Joda-Time解析器不支持时区:

SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM d, YYYY h:mm:ss a z");
Date d = df.parse("Thursday, July 27, 2006 10:10:02 PM PDT");

答案 3 :(得分:0)

您的代码有两个问题:

  1. 您使用了Y(指定周年)而不是y(指定)。查看 documentation 以了解有关符号的更多信息。详细了解它here
  2. 您的日期时间字符串是英文的,因此如果您在带有非英文 Locale 的 JVM 上运行您的代码,它不会以预期的方式工作。日期时间解析/格式化类型是 Locale 敏感的。详细了解here

java.time

旧的日期时间 API(java.util 日期时间类型及其格式 API,SimpleDateFormat)已经过时且容易出错。建议完全停止使用,改用java.timemodern date-time API*

使用现代 API 的解决方案:

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

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE, MMMM d, u h:m:s a z", Locale.ENGLISH);
        ZonedDateTime zdt = ZonedDateTime.parse("Thursday, July 27, 2006 10:10:02 PM PST", dtf);
        System.out.println(zdt);
    }
}

输出:

2006-07-27T22:10:02-07:00[America/Los_Angeles]

如果您需要将 ZonedDateTime 的这个对象转换为 java.util.Date 的对象,您可以这样做:

java.util.Date date = Date.from(zdt.toInstant());

modern date-time API 中了解有关 Trail: Date Time* 的更多信息。

使用旧 API 的解决方案:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM d, y h:m:s a z", Locale.ENGLISH);
        Date date = sdf.parse("Thursday, July 27, 2006 10:10:02 PM PST");
        //...
    }
}

* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project