Java LocalDateTime的总纳秒数
我正在处理Java LocalDateTime的总纳秒数,java,scala,date,time,Java,Scala,Date,Time,我正在处理LocalDateTime对象,并希望以纳秒精度将它们存储为Long 我尝试在即时表示之间进行转换,但到目前为止失败了 例如: localDateTime.toInstant(ZoneOffset.UTC).getNano 仅返回localDateTime的纳秒段-是否有方法以纳秒为单位返回完整值 与toepochssecond类似,但不是以秒为单位,而是以纳秒为单位?没有这种方法,因为您无法将所有瞬间存储在长的纳秒数中 如果您感到高兴的是,您感兴趣的日期范围可以在从纪元开始的纳秒数内
LocalDateTime
对象,并希望以纳秒精度将它们存储为Long
我尝试在即时
表示之间进行转换,但到目前为止失败了
例如:
localDateTime.toInstant(ZoneOffset.UTC).getNano
仅返回localDateTime
的纳秒段-是否有方法以纳秒为单位返回完整值
与
toepochssecond
类似,但不是以秒为单位,而是以纳秒为单位?没有这种方法,因为您无法将所有瞬间存储在长的
纳秒数中
如果您感到高兴的是,您感兴趣的日期范围可以在从纪元开始的纳秒数内全部匹配,您可以使用以下公式自行计算:
long nanos = ( instant.getEpochSecond * 1_000_000_000L ) + instant.getNano
请注意,如果日期在过去或将来太远,则会溢出。来自java API文档: 瞬间的范围需要存储大于1的数字 long。为了实现这一点,该类存储了一个长的 历元秒和一个表示纳秒的整数 始终介于0和99999999之间 那么从
Instant
获取的Nano总数无法在单个原语类型中检索,因为long
2262-04-11T23:47:16.854775807Z=long.MAX_值为Nano
在正确答案的基础上,解释自1970-01-01T00:00Z以来,64位长的整数不能将所有的瞬时值表示为纳秒计数
如果我的数学正确,您可以使用long
/long
以纳秒为单位来表示未来两个世纪的时刻,最长为2262-04-11T23:47:16.854775807Z
:
Instant.ofEpochSecond( ( Long.MAX_VALUE / 1_000_000_000L ) , ( Long.MAX_VALUE % 1_000_000_000L ) )
仅供参考,Long.MAX_值
=9223372036854775807
我不是说这样做是个好主意。我只是展示了展示手头问题的可能性
看
Long.MAX_值:9223372036854775807
秒:9223372036
分数:854775807
总数:9223372036854775807
瞬间:2262-04-11T23:47:16.854775807Z
从LocalDateTime对象获取自历元以来的纳秒总数的正确方法是:
从LocalDateTime对象创建一个即时对象
总结这两种方法的结果:
- getEpochSecond()-
- 获取Java纪元1970-01-01T00:00:00Z的秒数
- getNano()-
- 获取从第二个开始沿时间线稍后的纳秒数
示例代码
如果您的LocalDateTime
确实以UTC表示时间,那么这样做是有意义的。如果它位于某个(已知或未知)时区,则您尝试的是不正确的,并且容易导致混淆。@Dima,因为对于当前日期,值的顺序是2^60
或2^61
。因此,如果你将日期向某个方向移动几百年,它将溢出仅具有约±2^63
范围的长日期,日期将接近当前日期,因此此解决方案对我很有效。谢谢@Assylasi我仍然建议您检查溢流和下溢。一个简单的方法是将你的瞬间
与瞬间的秒数(0,长的最小值)
和瞬间的秒数(0,长的最大值)
(分别在1677年和2262年)。或者,如果这对您的情况更有意义,请验证您的日期是否在接近当前日期的较窄时间间隔内。@OleV.V。或者使用Math.multiplyExact(instant.getEpochSecond,1_000_000_000)
检查异常。这不是OP所问的问题,问题是如何获得自EPOCH以来的nano数,它适合long类型的变量。@cbaldan这清楚地解释了他想要的是不可能的,如果你愿意,你需要一个long和一个int,从EPOCH开始的纳秒数存储在96位中,这是博士说的。除非我不太理解问题的本质,否则我仍然不能同意。我将一个Long.MAX_值
转换为LocalDateTime,我想我们可以使用一个长变量来存储纳秒,直到2262-04-11T23:47:16.0000000 10
。我编写的代码没有正确添加剩余的纳秒,我无法编辑我以前的注释,但在我修复了这个总数之后,我得到的值与@Basil:2262-04-11T23:47:16.854775807
@cbaldan好的,所有这一切并不意味着没有日期不能存储在哪怕是一个字节中,但这可以移植,仅此而已。毕竟,如果类型/api/标准是为某种东西而设计的,那么它是为了可移植性,不是吗?
long seconds = ( Long.MAX_VALUE / 1_000_000_000L ) ;
long fraction = ( Long.MAX_VALUE % 1_000_000_000L ) ;
long total = ( ( seconds * 1_000_000_000L ) + fraction ) ;
Instant instant = Instant.ofEpochSecond( seconds , fraction ) ;
System.out.println( "Long.MAX_VALUE: " + Long.MAX_VALUE ) ;
System.out.println( "seconds: " + seconds ) ;
System.out.println( "fraction: " + fraction ) ;
System.out.println( "total: " + total ) ;
System.out.println( "instant: " + instant ) ;
public static void main(String args[]) {
Instant instant = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();
long epochNanos = TimeUnit.NANOSECONDS.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
epochNanos += instant.getNano();
System.out.print("Total nanos since EPOCH: " + epochNanos);
}