为什么将System.nanoTime()转换为Calendar对象会给我错误的当前日期?

3
如果我理解正确,使用System.nanoTime()System.currentTimeInMillis()更准确地保持当前时间的标记,即使系统时间被更改。那么为什么当我将nanoTime()的长整型值转换为Calendar对象时,输出结果是错误的?
import java.util.Calendar;

public class Test {

    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());
        System.out.println(c.get(Calendar.MONTH) + " " + c.get(Calendar.DATE) + " " + c.get(Calendar.YEAR) +
                " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND)
                + ":" + c.get(Calendar.MILLISECOND));
    }

}

2
nanoTime 返回纳秒级别的时间,如果将该值传递给 setTimeInMillis 方法,则会出现“单位不匹配”(ns 与 ms 不同)。 - user180100
我该如何解决单位不匹配的问题? - Matthew Quiros
2
你的代码与问题有什么关系?你没有使用nanoTime。要将纳秒转换为毫秒,只需要将其除以10^6即可 ;) - Burkhard
AmitD的答案也需要考虑进去! - user180100
通常情况下,当我的Android应用程序中的“Service”被执行时,我会保存当前时间。我阅读了类似问题,发现nanoTime()currentTimeInMillis()更适合作为当前时间的标记,因为后者在系统时间更改时可能会发生变化。我的理解是正确的吗? - Matthew Quiros
小心使用。将System.nanoTime()除以10^6不会给出自1970年以来的毫秒数。您不能使用System.nanoTime()的结果创建Timestamp或Date。 - Martin Försterling
1个回答

8

System.nanotime()的javadoc建议:

返回可用最精确系统计时器的当前值,以纳秒为单位。

此方法仅用于测量经过的时间,与任何其他系统或挂钟时间概念无关。返回的值表示自某个固定但任意的时间(可能是未来的时间,因此值可能为负)以来的纳秒数。此方法提供纳秒精度,但不一定具有纳秒准确性。不能保证值更改的频率。跨越大约292年(263纳秒)的连续调用之间的差异由于数字溢出而无法准确计算经过的时间。

例如,要测量某些代码执行所需的时间:

long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;

啊,所以nanoTime只有在计算精确到毫秒的持续时间时才有用...它不代表自1970年1月1日以来的纳秒数。我想知道为什么官方文档使用如此困难的英语来正确解释它。 - Ammar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接