我有一个愚蠢的问题,这是我的代码:
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zZ",Locale.US);
System.out.println(dateFormat.format(new Date()));
try {
wou.setDateStart(dateFormat.parse(date));
wou.setDateEnd(dateFormat.parse(date));
} catch (ParseException e) {
System.out.println(e.getCause() + " " + e.getMessage());
e.printStackTrace();
}
结果如下:
2015年6月5日星期五15:34:29 GMT + 0000
null无法解释日期:“2015年6月5日星期五17:30:00 GMT + 0000”
我的格式出了什么问题?它以与我想要解析的日期相同的格式输出当前日期,但一直告诉我日期是不可解析的......
我挣扎了一个多小时,我完全迷失了......
修改
我无法控制我需要解析的日期(如果我这样做,我会在源代码中将其更改为我可以使用的格式)
以下代码:
String date = request.getParameter("absencyDate");
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z",Locale.US);
try {
System.out.println(dateFormat.format(new Date()));
System.out.println(date);
System.out.println(dateFormat.parse(date));
} catch (ParseException e1) {
产生同样的错误:
2015年6月5日星期五16:09:15 GMT
2015年6月5日星期五12:30:00 GMT + 0000
java.text.ParseException:Unparseable date:“Fri Jun 05 2015 12:30:00 GMT + 0000”
答案 0 :(得分:4)
问题是您在日期格式中使用zZ
。它需要一个简单的基于名称的区域(z
),然后是RFC-822区域(Z
)。
如果默认区域(或格式中设置的区域)不是GMT,它运行良好,因为它只是解析到那一点(匹配z
),然后它解析{{1 } {} +0000
。
但是当区域是GMT时,它实际上会尝试解析跟随它的部分(Z
)作为+0000
的一部分,因为" GMT + hh:mm"是z
的有效区域,但失败了。
日期格式显示为欺骗性正确。但结合两种时区格式则不然。它应该是一个命名时区(包括" GMT + 00:00"),或RFC 822偏移(它不包括" GMT"指定)。
编辑OP编辑
因此,您从某处获得了z
参数,并且他们使用非标准区域指定将其发送给您。 date
既不匹配一般时区(应为GMT+0000
或GMT
),也不符合RFC 822时区(GMT+00:00
不应为+0000
),也不符合ISO 8601时间区域(应为GMT
或+00
或+0000
)。
如果您知道他们将在日期中始终使用+00:00
,我认为您可以做的最好的事情是:
GMT
将"EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
部分作为文字字符串而不是时区指示符,然后从其后面的任何内容解释时区。
或者,如果生成该参数的源在您的控制之下,请修改其格式以使用与其中一个标准匹配的正确时区。
答案 1 :(得分:0)
旧的日期时间 API(java.util
日期时间类型及其格式 API,SimpleDateFormat
)已经过时且容易出错。建议完全停止使用它们并切换到 java.time
,modern date-time API*。
使用现代日期时间 API 的演示:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
String dateStr = "Fri Jun 05 2015 17:30:00 GMT+0000";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("EEE MMM d u H:m:s")
.appendLiteral(' ')
.appendZoneId()
.appendPattern("X")
.toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(dateStr, dtf);
System.out.println(zdt);
}
}
输出:
2015-06-05T17:30Z[GMT]
出于任何原因,如果您需要 java.util.Date
的这个对象中的 ZonedDateTime
对象,您可以如下:
Date date = Date.from(zdt.toInstant());
从 modern date-time API 中了解有关 Trail: Date Time* 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。