java.sql.Timestamp 存储 NanoSeconds 的方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5839411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:02:54  来源:igfitidea点击:

java.sql.Timestamp way of storing NanoSeconds

javajdbctimestampnanotime

提问by Vicky

java.sql.Timestamp constructor go like this:

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

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.

它基本上以毫秒为单位接受时间,然后提取最后 3 位数字并使其成为 nanos。所以对于 1304135631 421的毫秒值,我得到 Timestamp.getnanos() 为 421000000。这是简单的计算(最后添加 6 个零)......似乎不是最佳的。

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.

如果您运行以下程序,您将看到实际纳秒与 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;
    }

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

所以所有关于 Timestamp 的讨论都说它存储时间高达纳秒,似乎不是那么正确..不是吗?

采纳答案by BalusC

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.

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

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

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

// ...

回答by Benjamin Gehrels

Since the introduction of java.time.*, there is a new factory method in java.sql.Timestamp: Timestamp.from(Instant.now())will do the job (with nanoseconds precision). There is also Timestamp.toInstant()to convert it the other way around.

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

回答by Shailendra

Although it's an old post, I would like to add that the docs of Timestamp does state that it "holds fractional seconds by allowing the specification of fractional seconds to a precision of nanaoseconds". The confusing part is "hold". This seems confusing at first but if understood correctly, it actually does not state that it holds nanaoseconds value.It says it "holds" fractional value and allows it to be a "precision" of nanoseconds. Precision should be understood in terms of representation of total number of digits. So it essentially means that the part is actually fractional (still milliseconds) but is multiplied by 1000000 to represent it as nanoseconds.

虽然这是一篇旧帖子,但我想补充一点,Timestamp 的文档确实指出它“通过允许小数秒的规范达到纳秒的精度来保持小数秒”。令人困惑的部分是“持有”。起初这似乎令人困惑,但如果理解正确,它实际上并没有说明它持有纳秒值。它说它“持有”小数值并允许它是纳秒的“精度”。精度应理解为总位数的表示。所以它本质上意味着该部分实际上是小数(仍然是毫秒),但乘以 1000000 以将其表示为纳秒。

The accepted answer (by ever helpful BaluC) sums it up nicely.

接受的答案(由曾经有帮助的 BaluC 提供)很好地总结了它。

回答by Stavr00

I like OpenJPA's implementation of TimestampHelper. It use static initializers to keep track of elapsed nanoseconds between calls to make a timestamp.

我喜欢 OpenJPA 的TimestampHelper实现。它使用静态初始值设定项来跟踪调用之间经过的纳秒以生成时间戳。