Java8 LocalDateTime和NANO_OF_SECOND奇怪的格式化

时间:2018-04-12 13:32:16

标签: java datetime java-8 datetime-format java-time

我试试这段代码:

import java.time.*; 
...
   LocalDateTime now = LocalDateTime.now();
   DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
                                    "dd-MMM-yyyy  HH:mm:ss.n");
   System.out.format("Now = %s %n", now.format(formatter));

以获得具有亚秒信息的输出 Now = 12-Apr-2018 14:47:38.039578300

不幸的是,在每秒的前100毫秒中,亚秒信息的前导零被省略,我得到一个非常误导的输出Now = 12-Apr-2018 14:47:38.39578300,这很容易被误解为大约38.4秒或396毫秒后整秒,而不是真正的38.04秒。

我找到的唯一工作方式是格式为ss.nnnnnnnnn且格式为9 n,以获得所需的输出。

修改

有一些更好的东西,在发布这个问题时我在这方面错过了。

我对Nanoseconds并不感兴趣,但是我只需要几秒钟的时间(大约是ms分辨率)。

然后,这个更适合

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");

大写字母S表示亚秒数字的数字,当然包括前导零。

3 个答案:

答案 0 :(得分:5)

为了更好地控制分数,您可以使用构建器,而不仅仅是模式字母。具体来说是appendFraction

Self

模式字母“n”很少是你想要的。

答案 1 :(得分:4)

如果您只需要ms分辨率,则可以使用S代替n

DateTimeFormatter formatter = DateTimeFormatter
    .ofPattern("dd-MMM-yyyy  HH:mm:ss.SSS", Locale.US);

这将仅打印前3个小数位(即ms分辨率):

  

2018年4月12日14:47:38.039

请注意,我使用java.util.Locale来定义用于月份名称的语言。这是因为JVM可能并不总是设置为英语,结果可能不是您所期望的。例如:我的JVM设置为葡萄牙语,月份名称为“abr”。设置特定的语言环境可以消除此问题。

要打印所有9位数,使用nnnnnnnnnSSSSSSSSS都可以。

当我们check the javadoc时,我们可以看到它为什么会这样。 Sn有不同的演示文稿:

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
S       fraction-of-second          fraction          978
n       nano-of-second              number            987654321

S分数,而n分数。文档告诉你区别:

  

数字:如果字母数一个,则使用最小位数输出值填充

     

分数:以秒为单位输出纳秒级字段。纳秒值有九位数,因此模式字母的数量从1到9. 如果小于9 ,那么纳秒值截断仅输出最高位数

所以,只有1 n会打印没有填充的值(开头没有0),导致输出错误,而SSS会给你正确的输出。

答案 2 :(得分:0)

我认为没有比nnnnnnnnn更好的东西了。对于n模式的per DateTimeFormatter docs,如果使用少于9个模式字母,则前导零将被截断:

  

分数:以秒为单位输出纳秒级字段。   纳秒值具有九位数,因此是图案的计数   字母是从1到9.如果它小于9,那么纳秒   值被截断,只有最高位数   输出

nN是DateTimeFormatter支持的唯一纳米字段。