AMT*_*erp 3 java java-8 java-time
我正在尝试做一些看似很简单的事情,但是我一生无法使它正常工作。
我想将某些字符串解析为LocalTime,然后以所需的格式打印它们。我想要的是:
HH:mm:ss(13:00:00打印为13:00:00)。13:45:20并且13:45:20.000两个都打印为13:45:20)13:45:20.01打印为13:45:20.010)根据以下文档,似乎可以在DateTimeFormatter中使用可选选项optionalStart:
All elements in the optional section are treated as optional.
During formatting, the section is only output if data is available in the
{@code TemporalAccessor} for all the elements in the section.
During parsing, the whole section may be missing from the parsed string.
Run Code Online (Sandbox Code Playgroud)
但是,强制将Millis保留为小数点后3位似乎绕过了可选方面,即.000在millis == 0时被打印:
final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendLiteral('.')
.appendValue(MILLI_OF_SECOND, 3)
.toFormatter();
System.out.println(formatter.format(LocalTime.parse("12:45:00"))); // Outputs 12:45:00.000, bad!
System.out.println(formatter.format(LocalTime.parse("12:45:00.000"))); // Outputs 12:45:00.000, bad!
System.out.println(formatter.format(LocalTime.parse("12:45:00.010"))); // Outputs 12:45:00.010, good!
Run Code Online (Sandbox Code Playgroud)
当然,可以通过条件来完成,手动检查millis!= 0,但是我想知道的是,是否可以通过不太明确的方式来实现。
谢谢堆!
混乱在于行为optionalStart。您期望它截断零毫秒值(因为您认为毫秒值不存在)。但是,optionalStart仅查看日期时间分量的存在,而不是值(因此,永远不会丢失时间的毫秒分量的“存在”)。可以将其视为没有毫秒的时间戳与具有零毫秒的时间戳之间的差异。
DateTimeFormatterBuilder.appendValue不声称截断小数点(https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatterBuilder.html#appendValue-java.time.temporal.TemporalField-int-),为了获得您想要的行为,请使用https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatterBuilder.html#appendFraction-java.time.temporal.TemporalField-int-int -布尔值-,例如
final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(MILLI_OF_SECOND, 0, 3, true)
.toFormatter();
Run Code Online (Sandbox Code Playgroud)
注意:您将小数位添加为文字,这意味着格式化程序无法理解您希望毫秒为小数。通常,如果要将值视为小数而不是整数,则库必须提供小数位。
编辑: 抱歉@AMterp不太符合预期的行为。具体来说,除非毫秒部分为零,否则应显示3个小数位。
为了实现这一点,不幸的是,我看不到一种java.time.DateTimeFormatter以这种方式表现的方法(没有内置函数支持该方法,而该类是内置的,final因此您无法覆盖实现)。相反,我可以建议两个选择:
.replace(".000", "")然后再运行,或者null)