1
    Date date = new Date();
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SZ");//2018-02-05T18:00:51.001+0000
    String text = dateFormat.format(date);

    Date test = dateFormat.parse(text);

前三行工作正常。当我再次尝试将字符串解析为日期时,出现错误。我该如何解决这个问题?

错误如下所示:

Caused by: java.text.ParseException: Unparseable date: "2018-02-07T15:32:13.214+0100"
    at java.text.DateFormat.parse(DateFormat.java:366) ~[na:1.8.0_151]
    at TimeRange.parseDateFromIsoString(TimeRange.java:33) ~[classes/:na]
4

3 回答 3

3
    Date date = new Date();
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");//2018-02-05T18:00:51.001+0000
    String text = dateFormat.format(date);

    try {
        Date test = dateFormat.parse(text);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

为我工作。在模式的末尾使用“SSSZ”而不是“SZ”。

于 2018-02-07T14:36:05.887 回答
1

我想贡献现代答案。因为我不鼓励使用SimpleDateFormat,稍后会详细介绍。

java.time

    OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("Europe/Rome"));
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
    String text = dateTime.format(formatter);
    OffsetDateTime test = OffsetDateTime.parse(text, formatter);

这会产生一个类似于 的字符串2018-02-07T17:51:21.087+0100,非常接近我认为您在问题中所追求的字符串,并且可以很好地解析它。在SSS格式模式字符串中,它总是在秒上产生 3 个小数,并且通过解析也需要 3 个小数。例如,您可以使用SSSSSSS获得 1 位或 6 位小数。在我的 Java 9OffsetDateTime.now()上,精度为 6 位小数(微秒),所以如果我指定的更少,我会失去格式的精度。

编辑:为了向后兼容,您不能使用以下内容,但对于任何阅读的人,我想提供一个没有显式格式化程序的变体:

    String text = dateTime.toString();
    OffsetDateTime test = OffsetDateTime.parse(text);

生成的字符串的两个区别是:

  1. 它产生尽可能多的 3 位小数组,以呈现精度。在我的 Java 8 上通常是 3 个小数,在我的 Java 9 上是 6 个小数,但有时它会达到毫秒的整数并产生更少的小数。它解析从 0 到 9 位小数的所有字符串,因此这不会在解析中出现问题。而且我始终保留原始OffsetDateTime对象的完整精度。
  2. 与 UTC 的偏移量以冒号呈现,例如+01:00.

你的代码出了什么问题?

这个SimpleDateFormat类早已过时并且出了名的麻烦,所以即使你目前没有遇到问题,我仍然建议你放弃它并使用java.time现代 Java 日期和时间 API,就像我在上面所做的那样。

SimpleDateFormat旧版和现代版之间的一个区别DateTimeFormatter是,虽然S在现代格式化程序中表示秒的几分之一,SimpleDateFormat但它表示毫秒,所以除三之外的任何其他数字都是没有意义的。但是,它接受其他数字。格式化时,您的格式化程序为毫秒生成了足够的数字,例如,89如果有 21.089 秒或214问题中的 13.214 时。前者不正确,21.089 秒被呈现为21.89. 我坚信三位数的毫秒数会导致您的解析失败,而您只有一个S. 在我的 Java 8 和 9 上,它可以工作,并且解析21.89为 21 秒 89 毫秒,因此错误会消失。

这种行为与 Java 9 文档一致,该文档指出:“对于格式化,模式字母的数量是最小位数,较短的数字在此数量上补零。对于解析,模式字母的数量会被忽略,除非需要分隔两个相邻的字段。”</p>

关联

于 2018-02-07T18:11:07.987 回答
0

我以与时区相关的简单日期格式删除了 Z 给出了正确的输出 下面是片段。

Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S");//2018-02-05T18:00:51.001+0000
String text = dateFormat.format(date);

try {
    Date test = dateFormat.parse(text);
} catch (ParseException e) {
    e.printStackTrace();
}
于 2018-02-07T14:33:29.913 回答