java.sql.Timestamp存储NanoSeconds的方法



java.sql.Timestamp构造函数如下所示:

public Timestamp(long time) {
    super((time/1000)*1000);
    nanos = (int)((time%1000) * 1000000);
    if (nanos < 0) {
        nanos = 1000000000 + nanos;     
        super.setTime(((time/1000)-1)*1000);
    }
}

它基本上接受以毫秒为单位的时间,然后提取最后3位数字,使其成为纳米。因此,对于1304135631421的毫秒值,我将Timestamp.getnanos((作为421000000。这是一个简单的计算(最后加6个零(。。。似乎不是最佳的。

一个更好的方法可能是Timestamp构造函数,它接受以纳秒为单位的时间,然后计算出其中的纳秒值。

如果您运行以下程序,您将看到实际纳秒与Timestamp计算纳米生态的方法返回的纳秒之间的差异。

long a = System.currentTimeMillis();
    for(;;){
        long b = System.currentTimeMillis();
        Timestamp tm = new Timestamp(System.currentTimeMillis());
        System.out.println(tm.getTime());
        System.out.println(tm.getNanos());
        System.out.println("This is actual nanos" + System.nanoTime()%1000000000);
        System.out.println("--------------------------");
        if(b-a >= 1)
            break;
    }

所以所有关于时间戳的讨论都说它可以存储纳秒的时间,这似乎并不正确。。不是吗?

以毫秒为单位的时间并不代表以纳米为单位的时刻。再精确不过了。你应该用Timestamp#setNanos()来设置真正的纳米。

long timeInMillis = System.currentTimeMillis();
long timeInNanos = System.nanoTime();
Timestamp timestamp = new Timestamp(timeInMillis);
timestamp.setNanos((int) (timeInNanos % 1000000000));
// ...

自从引入java.time.*以来,java.sql.Timestamp中有一种新的工厂方法:Timestamp.from(Instant.now())将完成这项工作(精度为纳秒(。还有Timestamp.toInstant()可以反过来转换它。

虽然这是一篇老文章,但我想补充一点,Timestamp的文档确实声明它"通过允许小数秒到纳奥秒的精度"。令人困惑的部分是"保持"。这一点一开始看起来很困惑,但如果理解正确,实际上并没有说明它保持纳奥秒价值它说它"保持"分数值,并允许它达到纳秒的"精度"。应从表述的角度理解精度总位数的。因此,它本质上意味着该部分实际上是分数(仍然是毫秒(,但乘以1000000表示为纳秒。

公认的答案(由一向乐于助人的巴鲁C(很好地总结了这一点。

我喜欢OpenJPA对TimestampHelper的实现。它使用静态初始化程序来跟踪调用之间经过的纳秒时间,以生成时间戳。

相关内容

  • 没有找到相关文章

最新更新