有没有一种方法可以创建LocalDateTime模式,该模式将解析具有至少毫秒精度但可选的微秒精度的日期/时间,即在接下来的毫秒日期/时间中可以正常解析,但第二个以毫秒为单位的日期/时间将失败。我认为模式[[“”]“中的可选指示符将允许这项工作:

DateTimeFormatter DATE_TIME_FORMATTER =
    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS[SSS]");
System.out.println(LocalDateTime.parse("2019-02-14 11:04:52.784", DATE_TIME_FORMATTER));
System.out.println(LocalDateTime.parse("2019-02-14 11:04:52.784108", DATE_TIME_FORMATTER));

最佳答案

哈克号1个

    String withMillis = "2019-02-14 11:04:52.784";
    String withMicros = "2019-02-14 11:04:52.784108";

    System.out.println(LocalDateTime.parse(withMillis.replace(' ', 'T')));
    System.out.println(LocalDateTime.parse(withMicros.replace(' ', 'T')));



2019-02-14T11:04:52.784
2019-02-14T11:04:52.784108



当我们用T替换字符串中间的空格时,该字符串符合ISO 8601,即LocalDateTime和其他java.time类的标准格式(也是打印)的默认格式,即是,没有任何显式格式化程序。因此,这是一个简单的解决方案。

哈克号2

像您尝试过的东西可以使您工作。只有您不能拆分中间带有方括号的SSSSSS序列。

static final DateTimeFormatter DATE_TIME_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.[SSSSSS][SSS]");


然后:

    System.out.println(LocalDateTime.parse(withMillis, DATE_TIME_FORMATTER));
    System.out.println(LocalDateTime.parse(withMicros, DATE_TIME_FORMATTER));


我可以指定6个小数,然后指定3个小数。我们需要那个命令。如果我们放入[SSS][SSSSSS]并尝试解析6个小数,则格式化程序将首先解析3个小数,然后引发异常,因为它无法使用SSSSSS解析其余3个小数。这有点骇人听闻,因为它也可以接受不带小数点的小数点,并且如果我们给它9个小数点的话,可能会发出非常混乱的错误消息(甚至可能给出错误的结果)。

好的解决方案:使用构建器

static final DateTimeFormatter DATE_TIME_FORMATTER =
        new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .appendPattern("HH:mm:ss")
                .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true)
                .toFormatter();


在此,我指定了小数点后最少1个和最多9个小数。如果愿意,可以指定3和6。当然,它也会接受4或5。

链接:Wikipedia article: ISO 8601

10-04 19:21