我在试图解析字符串值时得到解析器异常:
"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());
}
From 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");
根据marba的建议,这个错误很可能是由于在Java 6中使用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获取更多模式
您使用的语言环境是什么?我认为您必须明确地提供Locale.US
作为SimpleDateFormat
的第二个参数。
对于Joda-Time库,您可以使用以下代码来调整区域设置:
DateTimeFormat.forPattern("EEEE, MMMM d, YYYY h:mm:ss a z").withLocale(Locale.US);
更新:刚刚发现这个相关的SO问题,看起来你需要使用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");
你的代码有两个问题:
- 您使用了
Y
(指定周年)而不是y
(指定年)。查看文档以了解有关符号的更多信息。点击这里了解更多信息。 - 您的日期-时间字符串是英文的,因此如果您在具有非英文
Locale
的JVM上运行它,您的代码将无法以预期的方式工作。日期-时间解析/格式化类型是Locale
敏感的。点击这里了解更多信息。
java.time
遗留的日期时间API (java.util
日期时间类型和它们的格式化API, SimpleDateFormat
)已经过时并且容易出错。建议完全停止使用它,并切换到java.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());
了解更多关于现代日期时间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+可用的API,通过desugaring和如何在Android项目中使用ThreeTenABP。