Java8 LocalDateTime 和 NANO_OF_SECOND 奇怪的格式
Java8 LocalDateTime and NANO_OF_SECOND strange formatting
我试试这个代码:
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
,以获得我想要的输出。
编辑:
有更好的东西,我在发布这个问题时在这方面错过了。
我对纳秒不是很感兴趣,但秒的小数部分(大约 ms 分辨率)才是我真正想要的。
那这个更合适
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
大写的S表示亚秒数,当然包括前导零。
我认为没有比nnnnnnnnn
更好的了。由于 per DateTimeFormatter docs 对于 n
模式,如果使用少于 9 个模式字母,前导零将被截断:
Fraction: Outputs the nano-of-second field as a fraction-of-second.
The nano-of-second value has nine digits, thus the count of pattern
letters is from 1 to 9. If it is less than 9, then the nano-of-second
value is truncated, with only the most significant digits being
output.
n
和 N
是 DateTimeFormatter 唯一支持的纳米字段。
如果你只想要 ms 分辨率,你可以使用 S
而不是 n
:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("dd-MMM-yyyy HH:mm:ss.SSS", Locale.US);
这将只打印前 3 个小数位(这是 ms 分辨率):
12-Apr-2018 14:47:38.039
请注意,我使用了 java.util.Locale
来定义要用于月份名称的语言。那是因为 JVM 可能并不总是设置为英语,结果可能不是您所期望的。例如:我的 JVM 设置为葡萄牙语,月份名称为“abr”。设置特定的语言环境可以消除这个问题。
要打印所有 9 位数字,使用 nnnnnnnnn
或 SSSSSSSSS
都可以。
当我们 check the javadoc 时,我们可以看到为什么它会这样。 S
和 n
有不同的介绍:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
S fraction-of-second fraction 978
n nano-of-second number 987654321
S
是 分数 ,而 n
是 数字 。文档告诉你区别:
Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding.
Fraction: Outputs the nano-of-second field as a fraction-of-second. The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9. If it is less than 9, then the nano-of-second value is truncated, with only the most significant digits being output.
所以,只有 1 n
会打印没有填充的值(开头没有 0
),导致你得到错误的输出,而 SSS
会给你正确的输出。
要更好地控制分数,您可以使用生成器,而不仅仅是模式字母。具体来说 appendFraction.
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("dd-MMM-yyyy HH:mm:ss")
.appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true)
.toFormatter();
模式字母"n"很少是你想要的。
我试试这个代码:
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
,以获得我想要的输出。
编辑:
有更好的东西,我在发布这个问题时在这方面错过了。
我对纳秒不是很感兴趣,但秒的小数部分(大约 ms 分辨率)才是我真正想要的。
那这个更合适
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
大写的S表示亚秒数,当然包括前导零。
我认为没有比nnnnnnnnn
更好的了。由于 per DateTimeFormatter docs 对于 n
模式,如果使用少于 9 个模式字母,前导零将被截断:
Fraction: Outputs the nano-of-second field as a fraction-of-second. The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9. If it is less than 9, then the nano-of-second value is truncated, with only the most significant digits being output.
n
和 N
是 DateTimeFormatter 唯一支持的纳米字段。
如果你只想要 ms 分辨率,你可以使用 S
而不是 n
:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("dd-MMM-yyyy HH:mm:ss.SSS", Locale.US);
这将只打印前 3 个小数位(这是 ms 分辨率):
12-Apr-2018 14:47:38.039
请注意,我使用了 java.util.Locale
来定义要用于月份名称的语言。那是因为 JVM 可能并不总是设置为英语,结果可能不是您所期望的。例如:我的 JVM 设置为葡萄牙语,月份名称为“abr”。设置特定的语言环境可以消除这个问题。
要打印所有 9 位数字,使用 nnnnnnnnn
或 SSSSSSSSS
都可以。
当我们 check the javadoc 时,我们可以看到为什么它会这样。 S
和 n
有不同的介绍:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
S fraction-of-second fraction 978
n nano-of-second number 987654321
S
是 分数 ,而 n
是 数字 。文档告诉你区别:
Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding.
Fraction: Outputs the nano-of-second field as a fraction-of-second. The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9. If it is less than 9, then the nano-of-second value is truncated, with only the most significant digits being output.
所以,只有 1 n
会打印没有填充的值(开头没有 0
),导致你得到错误的输出,而 SSS
会给你正确的输出。
要更好地控制分数,您可以使用生成器,而不仅仅是模式字母。具体来说 appendFraction.
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("dd-MMM-yyyy HH:mm:ss")
.appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true)
.toFormatter();
模式字母"n"很少是你想要的。