Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java LocalDateTime的总纳秒数_Java_Scala_Date_Time - Fatal编程技术网

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);
    }