如何在 java 中获取字符串格式时间“2019-01-25 14:34:34.123456789”自纪元以来的纳秒数?
How to get nanoseconds since epoch for string formatted time "2019-01-25 14:34:34.123456789" in java?
我能够解析 2019-01-25 14:34:34.123456789
字符串并获取 ZonedDateTime
的对象。
现在,我想从这个 ZonedDateTime
对象中获取自纪元以来的纳秒精度级别的时间。
Duration 可能有帮助:
类似于:
Duration.between(
ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("UTC")),
yourZonedDatetime
).toNanos()
这将一直有效到 2262 年:
ZonedDateTime zdt = LocalDateTime.of(2019, 1, 25, 14, 34, 34, 123456789)
.atZone(ZoneId.of("Asia/Kolkata"));
Instant i = zdt.toInstant();
long epochNano = Math.addExact(Math.multiplyExact(i.getEpochSecond(), TimeUnit.SECONDS.toNanos(1)),
i.getNano());
System.out.println(NumberFormat.getNumberInstance(Locale.ENGLISH).format(epochNano));
输出:
1,548,407,074,123,456,789
为什么我不只是使用 TimeUnit.SECONDS.toNanos(i.getEpochSecond())
是因为在溢出的情况下这只会给我 Long.MAX_VALUE
,即不正确的结果。 Math.multiplyExact
会在溢出时抛出异常,所以我们会发现,我显然更喜欢。
为避免在 2262 年及以后出现溢出,请使用 BigInteger
:
BigInteger epochNano = BigInteger.valueOf(i.getEpochSecond())
.multiply(BigInteger.valueOf(TimeUnit.SECONDS.toNanos(1)))
.add(BigInteger.valueOf(i.getNano()));
结果是一样的
优点和缺点:我的代码比 Slawomir Chodnicki 的代码多了一点手工,这当然是一个缺点。另一方面,我也没有发现这里使用 Duration
的动机非常好,而且在 2262 年之后也不会起作用(抛出 ArithmeticException
)。完美的解决方案并不存在。
我能够解析 2019-01-25 14:34:34.123456789
字符串并获取 ZonedDateTime
的对象。
现在,我想从这个 ZonedDateTime
对象中获取自纪元以来的纳秒精度级别的时间。
Duration 可能有帮助:
类似于:
Duration.between(
ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("UTC")),
yourZonedDatetime
).toNanos()
这将一直有效到 2262 年:
ZonedDateTime zdt = LocalDateTime.of(2019, 1, 25, 14, 34, 34, 123456789)
.atZone(ZoneId.of("Asia/Kolkata"));
Instant i = zdt.toInstant();
long epochNano = Math.addExact(Math.multiplyExact(i.getEpochSecond(), TimeUnit.SECONDS.toNanos(1)),
i.getNano());
System.out.println(NumberFormat.getNumberInstance(Locale.ENGLISH).format(epochNano));
输出:
1,548,407,074,123,456,789
为什么我不只是使用 TimeUnit.SECONDS.toNanos(i.getEpochSecond())
是因为在溢出的情况下这只会给我 Long.MAX_VALUE
,即不正确的结果。 Math.multiplyExact
会在溢出时抛出异常,所以我们会发现,我显然更喜欢。
为避免在 2262 年及以后出现溢出,请使用 BigInteger
:
BigInteger epochNano = BigInteger.valueOf(i.getEpochSecond())
.multiply(BigInteger.valueOf(TimeUnit.SECONDS.toNanos(1)))
.add(BigInteger.valueOf(i.getNano()));
结果是一样的
优点和缺点:我的代码比 Slawomir Chodnicki 的代码多了一点手工,这当然是一个缺点。另一方面,我也没有发现这里使用 Duration
的动机非常好,而且在 2262 年之后也不会起作用(抛出 ArithmeticException
)。完美的解决方案并不存在。