Java 使用可选的尾部截断零将字符串解析为LocalDateTime
从API传递的字符串通常遵循格式Java 使用可选的尾部截断零将字符串解析为LocalDateTime,java,string,parsing,datetime-format,Java,String,Parsing,Datetime Format,从API传递的字符串通常遵循格式yyyy-MM-dd HH:MM:ss.SSS,但当时间戳中有尾随的0时,它们会被截断,例如,2019-07-16 13:29:15.100转换为2019-07-16 13:29:15.1,2019-07-16 13:29:15.110转换为2019-07-16 13:29:15.11。我有一个有效的解决方案,它只是用零填充结尾,但这感觉像是可以通过DateTimeFormatter字符串中的可选部分来解决的问题。最接近工作解决方案的方法如下: String to
yyyy-MM-dd HH:MM:ss.SSS
,但当时间戳中有尾随的0时,它们会被截断,例如,2019-07-16 13:29:15.100
转换为2019-07-16 13:29:15.1
,2019-07-16 13:29:15.110
转换为2019-07-16 13:29:15.11
。我有一个有效的解决方案,它只是用零填充结尾,但这感觉像是可以通过DateTimeFormatter字符串中的可选部分来解决的问题。最接近工作解决方案的方法如下:
String toParse = "2019-07-16 13:29:15.111";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.[S[S[S]]]]");
LocalDateTime timestamp = LocalDateTime.parse(toParse, formatter);
这适用于所有尾随零被截断的情况,但不适用于显示的毫秒内所有数字均为非零的情况。错误消息是
java.time.format.DateTimeParseException: Text '2019-07-16 13:29:15.111' could not be parsed, unparsed text found at index 21
这只是括号放置的问题吗?我使用的是Java 8,我们无法更改API传递的内容。这些可选括号中的毫秒并不完美,但您可以使用 使用内置部件 编写自己的格式模式字符串不仅有时很棘手,而且总是容易出错。我建议您使用内置部件组装格式化程序:
String toParse = "2019-07-16 13:29:15.111";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
LocalDateTime timestamp = LocalDateTime.parse(toParse, formatter);
System.out.println(timestamp);
输出:
2019-07-16T13:29:15.111
这一方法完全不使用小数(2019-07-16 13:29:15
),从一个小数(2019-07-16 13:29:15.1
)到九个小数(2019-07-16 13:29:15.123456789
)。它甚至可以在没有秒的情况下工作(2019-07-16 13:29
)
如果要抛出4位或更多小数的异常,则需要使用Deadpool答案中的appendFraction()
它在DateTimeFormatter.ISO\u LOCAL\u TIME
的文档中:
格式包括:
- 两位数字表示一天中的小时。这是预先填充的零,以确保两位数字
- 冒号
- 两位数字表示小时分钟。这是预先填充的零,以确保两位数字
- 如果第二分钟不可用,则格式已完成
- 冒号
- 两位数字表示一分钟的第二位。这是预先填充的零,以确保两位数字
- 如果nano of second为零或不可用,则格式已完成
- 小数点
- 一到九个数字表示纳秒。将根据需要输出尽可能多的数字
.111
时,它可以毫无例外地运行,但它可能会被理解为.1
,其中1
被指定三次。如果三位数字不相等,则将断开。相反,您可能会使用[[SSS][SS][S]]
作为可选小数点,后跟3、2或1个小数点。你需要把3个小数放在第一位
链接
2019-07-16T13:29:15.111
。在我的Java 11上观察到:2019-07-16T13:29:15.100
。有关解释,请参见我的答案。@OleV.V。啊。。。我实际上没有检查解析的结果。我只是指出没有得到提到的例外。哇,我不知道方括号能打破重复模式!学到了一些新东西,这很有效!我试着用括号来装腔作势,但这似乎是一个更健壮的解决方案。
String toParse = "2019-07-16 13:29:15.111";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
LocalDateTime timestamp = LocalDateTime.parse(toParse, formatter);
System.out.println(timestamp);