技巧一
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的其他类默认解析(和打印)的格式,也就是说,没有任何显式格式化程序。因此,这是一个简单的解决方案。
第二个技巧:
像您尝试的那样,可以使其工作。只是您不能使用中括号在
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位小数。这有点像一个hack,因为它还将接受没有任何小数点的小数点,并且如果我们给它9个小数,可能会发出非常令人困惑的错误消息(或者甚至给出不正确的结果)。
好的解决方案:使用生成器
编辑:自第一个答案版本以来,我已经稍微改进了生成器。
static final DateTimeFormatter DATE_TIME_FORMATTER =
new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
DateTimeFormatter.ISO_LOCAL_TIME
可以解析从0到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位。
链接:维基百科文章:ISO 8601