java.text.ParseException: Unparseable date “yyyy-MM-dd'T'HH:mm:ss.SSSZ“ - SimpleDateFormat

我将不胜感激任何帮助,以查找此异常的错误:

java.text.ParseException: Unparseable date: "2007-09-25T15:40:51.0000000Z"

和以下代码:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
Date date = sdf.parse(timeValue);
long mills = date.getTime();
this.point.time = String.valueOf(mills);

它抛出带有 .Date date = sdf.parse(timeValue);

timeValue = "2007-09-25T15:40:51.0000000Z";,如例外。

谢谢。


答案 1

Z表示时区字符。它需要被引用:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

答案 2

(答案现已广泛修订,感谢您在评论中的更正)

Java 7 中,您可以使用该模式来匹配 ISO8601 时区,其中包括特殊 (UTC) 值。XZ

该模式还支持显式时区,例如X+01:00

此方法正确遵循时区指示器,并避免了仅将其视为字符串的问题,从而错误地解析本地时区中的时间戳,而不是 UTC 或其他任何内容。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = sdf.parse("2007-09-25T15:40:51Z");
Date date2 = sdf.parse("2007-09-25T15:40:51+01:00");

这也可以与毫秒一起使用:

SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date3 = sdf2.parse("2007-09-25T15:40:51.500Z");

但是,正如其他人所指出的那样,您的格式具有7位小数秒,大概是十分之一微秒。如果是这样,则无法处理此问题,并且您将获得不正确的结果,因为每0.1微秒将被解释为毫秒,从而给出高达10,000秒(几个小时)的潜在总体误差。SimpleDateFormat

在极端情况下,如果秒的小数值为 0.9999999 秒,则会错误地解释为9999999 毫秒,即大约 167 分钟或 2.8 小时。

// Right answer, error masked for zero fractional seconds 
Date date6 = sdf2.parse("2007-09-25T15:40:51.0000000Z");
// Tue Sep 25 15:40:51 GMT 2007

// Error - wrong hour
// Should just half a second different to the previous example
Date date5 = sdf2.parse("2007-09-25T15:40:51.5000000Z");
// Tue Sep 25 17:04:11 GMT 2007

当秒的小数部分为零时,此错误是隐藏的,如您的示例所示,但只要它们不为零,就会显现出来。

在许多情况下,可以通过关闭“宽松”解析来检测此错误,并降低其影响,默认情况下,该解析将接受超过一秒的小数部分并将其传递到秒/分钟/小时部分:

sdf2.setLenient(false);
sdf2.parse("2007-09-25T15:40:51.5000000Z");
// java.text.ParseException: Unparseable date: "2007-09-25T15:40:51.5000000Z"

我建议始终禁用宽松解析,除非您有特定的需要,因为它会捕获许多错误,否则这些错误将被静默隐藏并传播到下游数据中。

如果您的秒数小数部分始终为零,则可以在此处使用其中一种解决方案,但如果以后在非零秒内使用代码,则它们将不起作用。您可能希望记录这一点和/或断言该值为零,以避免以后的错误。

否则,您可能需要将秒的小数部分转换为毫秒,以便正确解释它们。或者使用较新的日期时间 API 之一。SimpleDateFormat