Java simpledateformat 无法解析的日期,即使格式看起来是正确的
Java simpledateformat Unparseable date, even though the format appears to be right
我遇到了一个愚蠢的问题,这是我的代码:
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 无法解析的日期:"Fri Jun 05 2015 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格林威治标准时间
2015 年 6 月 5 日,星期五 12:30:00 GMT+0000
java.text.ParseException:无法解析的日期:"Fri Jun 05 2015 12:30:00 GMT+0000"
问题是您在日期格式中使用了 zZ
。它需要一个简单的基于名称的区域 (z
),然后是一个 RFC-822 区域 (Z
)。
如果默认时区(或格式中设置的时区)不是 GMT,它会很好地工作,因为它只解析到那个点(匹配 z
),然后解析 +0000
作为 Z
.
但是当区域是 GMT 时,它实际上会尝试将它后面的部分 (+0000
) 解析为 z
的一部分,因为 "GMT+hh:mm" 是一个有效区域z
,但失败了。
日期格式看似正确。但是结合两种时区格式不是。它应该是一个命名时区(包括 "GMT+00:00"),或者一个 RFC 822 偏移量(不包括 "GMT" 指定)。
按照 OP 编辑进行编辑
所以你从某个地方得到你的 date
参数,他们用非标准的区域指定发送给你。 GMT+0000
既不匹配一般时区(应为 GMT
或 GMT+00:00
)、RFC 822 时区(应为 +0000
而没有 GMT
),也不匹配 ISO 8601 时间区域(应为 +00
或 +0000
或 +00:00
)。
如果你知道他们在约会时总是使用 GMT
,我认为你能做的最好的事情是:
"EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
它将 GMT
部分作为文字字符串而不是时区指示符,然后从其后的任何内容解释时区。
或者,如果生成该参数的源在您的控制之下,请修复其格式以使用与标准之一匹配的正确时区。
java.time
旧版日期时间 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]
出于任何原因,如果您需要从 ZonedDateTime
这个对象中得到一个 java.util.Date
的对象,您可以这样做:
Date date = Date.from(zdt.toInstant());
从 Trail: Date Time[=46= 中了解有关 modern date-time API* 的更多信息].
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and 。
我遇到了一个愚蠢的问题,这是我的代码:
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 无法解析的日期:"Fri Jun 05 2015 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格林威治标准时间
2015 年 6 月 5 日,星期五 12:30:00 GMT+0000
java.text.ParseException:无法解析的日期:"Fri Jun 05 2015 12:30:00 GMT+0000"
问题是您在日期格式中使用了 zZ
。它需要一个简单的基于名称的区域 (z
),然后是一个 RFC-822 区域 (Z
)。
如果默认时区(或格式中设置的时区)不是 GMT,它会很好地工作,因为它只解析到那个点(匹配 z
),然后解析 +0000
作为 Z
.
但是当区域是 GMT 时,它实际上会尝试将它后面的部分 (+0000
) 解析为 z
的一部分,因为 "GMT+hh:mm" 是一个有效区域z
,但失败了。
日期格式看似正确。但是结合两种时区格式不是。它应该是一个命名时区(包括 "GMT+00:00"),或者一个 RFC 822 偏移量(不包括 "GMT" 指定)。
按照 OP 编辑进行编辑
所以你从某个地方得到你的 date
参数,他们用非标准的区域指定发送给你。 GMT+0000
既不匹配一般时区(应为 GMT
或 GMT+00:00
)、RFC 822 时区(应为 +0000
而没有 GMT
),也不匹配 ISO 8601 时间区域(应为 +00
或 +0000
或 +00:00
)。
如果你知道他们在约会时总是使用 GMT
,我认为你能做的最好的事情是:
"EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
它将 GMT
部分作为文字字符串而不是时区指示符,然后从其后的任何内容解释时区。
或者,如果生成该参数的源在您的控制之下,请修复其格式以使用与标准之一匹配的正确时区。
java.time
旧版日期时间 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]
出于任何原因,如果您需要从 ZonedDateTime
这个对象中得到一个 java.util.Date
的对象,您可以这样做:
Date date = Date.from(zdt.toInstant());
从 Trail: Date Time[=46= 中了解有关 modern date-time API* 的更多信息].
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and