java.time.DateTimeFormatter :需要始终呈现毫秒的 ISO_INSTANT
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38042134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.time.DateTimeFormatter : Need ISO_INSTANT that always renders milliseconds
提问by Florent
I'm trying to cleanup a mix of various code around datetime management to only Java 8 java.time
namespace. Right now I have a small issue with the default DateTimeFormatter
for Instant
. The DateTimeFormatter.ISO_INSTANT
formatter only shows milliseconds when they are not equal to zero.
我正在尝试将有关日期时间管理的各种代码混合清理到 Java 8java.time
命名空间。现在我有一个小问题用默认DateTimeFormatter
的Instant
。该DateTimeFormatter.ISO_INSTANT
格式只能说明毫秒时,他们不等于零。
The epoch is rendered as 1970-01-01T00:00:00Z
instead of 1970-01-01T00:00:00.000Z
.
时代被呈现为1970-01-01T00:00:00Z
而不是1970-01-01T00:00:00.000Z
。
I made a unit test to explain the problem and how we need to final dates to be compared one to each other.
我做了一个单元测试来解释这个问题以及我们需要如何将最终日期相互比较。
@Test
public void java8Date() {
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
String epoch, almostEpoch, afterEpoch;
{ // before epoch
java.time.Instant instant = java.time.Instant.ofEpochMilli(-1);
almostEpoch = formatter.format(instant);
assertEquals("1969-12-31T23:59:59.999Z", almostEpoch );
}
{ // epoch
java.time.Instant instant = java.time.Instant.ofEpochMilli(0);
epoch = formatter.format(instant);
// This fails, I get 1970-01-01T00:00:00Z instead
assertEquals("1970-01-01T00:00:00.000Z", epoch );
}
{ // after epoch
java.time.Instant instant = java.time.Instant.ofEpochMilli(1);
afterEpoch = formatter.format(instant);
assertEquals("1970-01-01T00:00:00.001Z", afterEpoch );
}
// The end game is to make sure this rule is respected (this is how we order things in dynamo):
assertTrue(epoch.compareTo(almostEpoch) > 0);
assertTrue(afterEpoch.compareTo(epoch) > 0); // <-- This assert would also fail if the second assert fails
{ // to confirm we're not showing nanos
assertEquals("1970-01-01T00:00:00.000Z", formatter.format(Instant.EPOCH.plusNanos(1)));
assertEquals("1970-01-01T00:00:00.001Z", formatter.format(Instant.EPOCH.plusNanos(1000000)));
}
}
采纳答案by Florent
OK, I looked at the the source code and it's pretty straightforward:
好的,我查看了源代码,它非常简单:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendInstant(3).toFormatter();
I hope it works for all scenarios, and it can help someone else. Don't hesitate to add a better/cleaner answer.
我希望它适用于所有场景,并且可以帮助其他人。不要犹豫,添加一个更好/更清晰的答案。
Just to explain where it comes from, in the JDK's code,
只是为了解释它的来源,在 JDK 的代码中,
ISO_INSTANT
is defined like this:
ISO_INSTANT
定义如下:
public static final DateTimeFormatter ISO_INSTANT;
static {
ISO_INSTANT = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendInstant()
.toFormatter(ResolverStyle.STRICT, null);
}
And DateTimeFormatterBuilder::appendInstant
is declared as:
并DateTimeFormatterBuilder::appendInstant
声明为:
public DateTimeFormatterBuilder appendInstant() {
appendInternal(new InstantPrinterParser(-2));
return this;
}
And the constructor InstantPrinterParser
signature is:
构造函数InstantPrinterParser
签名是:
InstantPrinterParser(int fractionalDigits)
回答by Basil Bourque
The accepted Answer by Florentis correct and good.
在由弗洛朗接受的答案是正确的,好的。
I just want to add some clarification.
我只想补充一些说明。
The mentioned formatter, DateTimeFormatter.ISO_INSTANT, is default only for the Instant
class. Other classes such as OffsetDateTime
and ZonedDateTime
may use other formatters by default.
提到的格式化程序DateTimeFormatter.ISO_INSTANT仅适用于Instant
该类。其他类,例如OffsetDateTime
和ZonedDateTime
可能默认使用其他格式化程序。
The java.time classes offer a resolution up to nanosecond, much finer granularity than milliseconds. That means up to 9 digits in the decimal fraction rather than merely 3 digits.
java.time 类提供高达纳秒的分辨率,比毫秒更精细的粒度。这意味着小数部分最多有 9 位数字,而不仅仅是 3 位数字。
The behavior of DateTimeFormatter.ISO_INSTANT
varies by the number of digits in the decimal fraction. As the doc says (emphasis mine):
的行为DateTimeFormatter.ISO_INSTANT
因小数部分的位数而异。正如文档所说(强调我的):
When formatting, the second-of-minute is always output. The nano-of-second outputs zero, three, six or nine digitsas necessary.
格式化时,总是输出分钟的秒数。纳秒根据需要输出零、三、六或九位数字。
So depending on the data value contained within the Instant
object, you may see any of these outputs:
因此,根据Instant
对象中包含的数据值,您可能会看到以下任何输出:
2011-12-03T10:15:30Z
2011-12-03T10:15:30.100Z
2011-12-03T10:15:30.120Z
2011-12-03T10:15:30.123Z
2011-12-03T10:15:30.123400Z
2011-12-03T10:15:30.123456Z
2011-12-03T10:15:30.123456780Z
2011-12-03T10:15:30.123456789Z
2011-12-03T10:15:30Z
2011-12-03T10:15:30.100Z
2011-12-03T10:15:30.120Z
2011-12-03T10:15:30.123Z
2011-12-03T10:15:30.123400Z
2011-12-03T10:15:30.123456Z
2011-12-03T10:15:30.123456780Z
2011-12-03T10:15:30.123456789Z
The Instant
class is meant to be the basic building block of java.time. Use it frequently for data passing, data storage, and data exchange. When generating String representations of the data for presentation to users, use OffsetDateTime
or ZonedDateTime
.
该Instant
班,就是要java.time的基本构建块。经常将其用于数据传递、数据存储和数据交换。在生成数据的字符串表示以呈现给用户时,请使用OffsetDateTime
或ZonedDateTime
。