java.sql.Timestamp 存储 NanoSeconds 的方式

2022-01-13 00:00:00 timestamp jdbc java nanotime

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

java.sql.Timestamp constructor go like this:

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 位数字并将其设为 nanos.所以对于 1304135631 421 的毫秒值,我得到 Timestamp.getnanos() 为421000000.这是简单的计算(最后添加 6 个零)......似乎不是最佳的.

It basically accepts time in millisecond and then extracts the last 3 digits and makes it nanos. So for a millisecond value of 1304135631 421, I'm getting Timestamp.getnanos() as 421000000. This is plain calculation (adding 6 zeroes at the end)... does not seems to be optimum.

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

A better way could have been Timestamp constructor that accepts time in nanoseconds and then calculates the nanosecond value out of that.

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

If you run the below program, you'll see the difference between actual nanoseconds and the one returned by Timestamp way of calculating nanosecods.

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 的讨论都说它存储时间长达纳秒,似乎并不那么正确.不是吗?

So all the discussion about Timestamp that says it stores time up to nanoseconds , does not seems to be so correct.. Isn't?

推荐答案

以毫秒为单位的时间不代表以纳秒为单位的时间.更准确地说,它根本不可能.你应该使用 Timestamp#setNanos() 设置真正的 nanos.

The time in millis does not represent the time in nanos. More precise it simply can't be. You're supposed to use Timestamp#setNanos() to set the real nanos.

long timeInMillis = System.currentTimeMillis();
long timeInNanos = System.nanoTime();

Timestamp timestamp = new Timestamp(timeInMillis);
timestamp.setNanos((int) (timeInNanos % 1000000000));

// ...

相关文章