我能够解析2019-01-25 14:34:34.123456789
字符串并获取ZonedDateTime
的对象。
现在,我想从此ZonedDateTime
对象开始到以纪元为准,以纳秒为单位的时间。
答案 0 :(得分:1)
Duration可能有帮助:
类似的东西:
Duration.between(
ZonedDateTime.ofInstant(Instant.EPOCH, ZoneId.of("UTC")),
yourZonedDatetime
).toNanos()
答案 1 :(得分:0)
这将一直持续到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
)。完美的解决方案不存在。