Java SimpleDataFormat解析时间不正确

Java SimpleDataFormat解析时间不正确,java,simpledateformat,java-time,Java,Simpledateformat,Java Time,这种情况发生在一个可能更多的datetime上,其中时间部分在解析中完全错误 守则: import java.text.*; import java.util.*; public class TestTimeParse { public static void main(String[] args) { SimpleDateFormat dateFmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFor

这种情况发生在一个可能更多的datetime上,其中时间部分在解析中完全错误

守则:

import java.text.*;
import java.util.*;

public class TestTimeParse {
    public static void main(String[] args) {
        SimpleDateFormat dateFmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.getDefault());
        dateFmt.applyPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
        ParsePosition pos = new ParsePosition(0);
        Date date = dateFmt.parse("2018-11-01T18:07:55.6725292Z", pos);
        System.out.println("Text 2018-11-01T18:07:55.6725292Z parses as " + date);
    }
}
输出:

文本2018-11-01T18:07:55.6725292Z解析为周四11月1日20:00:00 MDT 2018年

时间部分发生了什么?小时是错误的,分钟和秒是零。

这是过时的日期、日历和SimpleDateFormat类。您不应该使用它,因为它被Java8中新的日期和时间API所取代。它在java.time包中提供


SimpleDataFormat似乎最多只能读取3毫秒的数字。如果将日期的小数部分截断为三位数字,即2018-11-01T18:07:55.672而不是2018-11-01T18:07:55.6725292Z,并且还更改相应的“S”模式说明符,即yyyy-MM-dd'T'HH:MM:ss.SSS'Z,则解析过程会起作用。

您介意解释确切的问题是什么吗?众所周知,旧API在大多数情况下都能工作。为什么不能在这里工作?我认为问题在于SimpleDataFormat的分辨率只有毫秒。您指定的精度远远高于可用的三位数000-999毫秒。SimpleDataFormat可能会与越界条件混淆。@ernest_k 6725292毫秒等于1小时52分5.292秒。将这些值添加到时间18:07:55中,以获得-是,精确地说是20:00:00.292-由于未打印毫秒,因此呈现为20:00:00。@OleV.V。谢谢你解开这个谜。没有任何显式的格式化程序,我无法使itMC更简单更好:要么就是Instant.parsestr,要么就是OffsetDateTime.parsestr。这是因为格式是标准ISO 8601。将模式更改为yyyy-MM-dd'T'HH:MM:ss.SSS'Z'并将输入更改为2018-11-01T18:07:55.672Z似乎可以解决问题。不确定这是否是与亚秒值相关的错误…如果可以的话。。。大多数情况下,人们编写的日期格式解析器的模式为yyyy-MM-dd'T'HH:MM:ss.sssss'Z'实际上是在解析ISO-8601日期时间。使用这种固定的、基于字符串的、不知道时区的模式解析ISO8601日期是一个糟糕的想法。所以,如果这确实是您要做的,那么看看java.util.Date只能处理毫秒。因此,SimpleDataFormat对此唯一支持的模式是yyyy-MM-dd'T'HH:MM:ss.SSS'Z',这意味着日期也必须用毫秒表示。我建议您不要使用DateFormat和Date。这些类设计得很糟糕,而且早已过时,其中前者尤其令人讨厌。而是使用LocalDateTime和DateTimeFormatter,两者都来自@OleV.V。我同意。不幸的是,这是在Java1.8之前编写的代码,我们需要对其进行重构。但与此同时,我们需要与之合作。
String str = "2018-11-01T18:07:55.6725292Z";
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'";

LocalDateTime ts = LocalDateTime.parse(str, DateTimeFormatter.ofPattern(pattern));
System.out.println("Text 2018-11-01T18:07:55.6725292Z parses as " + ts);