首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java DateTimeFormatter:仅将毫秒打印到3位(如果不是0)

Java DateTimeFormatter:仅将毫秒打印到3位(如果不是0)
EN

Stack Overflow用户
提问于 2019-11-26 01:21:04
回答 1查看 982关注 0票数 2

我试着做一些看似很简单的事情,但我无法让它在我的生活中发挥作用。

我希望将某些字符串解析为LocalTime,然后以所需的格式打印它们。我想要的是:

13:00:00).

  • Only

  • 总是至少打印HH:mm:ss (13:00:00打印为毫秒,如果它们!= 0 (13:45:2013:45:20.000都打印为13:45:20)

  • If打印毫秒),总是将它们打印到三个位置。( 13:45:20.010)

格式的13:45:20.01打印

根据DateTimeFormatter的文档,应该可以在optionalStart中使用选项词。

代码语言:javascript
复制
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.

但是,为millis强制执行3位小数似乎绕过了可选的方面,即当millis .000 0时打印==:

代码语言:javascript
复制
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!

当然,它可以通过条件,手动检查millis != 0,但我想知道的是,这是否有可能通过不太明确的手段。

谢谢大堆!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-26 01:51:11

混淆与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-boolean-

代码语言:javascript
复制
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();

注意:您将小数位添加为文字,这意味着格式化程序无法理解您希望将毫秒作为分数。通常,如果要将值视为分数而不是整数,库必须提供小数位。

编辑:向@AMterp道歉,因为它与预期的行为不完全匹配。具体来说,除非毫秒分量为零,否则应显示小数点3位。

为了实现这一点,不幸的是,我无法找到一种让java.time.DateTimeFormatter以这种方式运行的方法(内置函数中没有一个支持此功能,类是final,因此不能覆盖实现)。相反,我可以提出两种选择:

null)

  • 总是显示3位小数,然后运行.replace(".000", ""),如果时间戳为0,

  • 将移除它的毫秒分量(即设置为

  • )。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59042382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档