计算时间差的正确姿势

 第一步先摆出结论,第二步摆出证据证明

结论

来自阿里开发手册: 

获取当前毫秒数System.currentTimeMillis(),而不是new Date().getTime();

注意:如果想要获取更加精确的纳秒级时间值,使用System.nanoTime()的方式。

在jdk8中,针对统计时间等场景,推荐使用Instant类。

直白点就是: 当想获取当前毫秒数时,System.currentTimeMillis()优于new Date().getTime()。 如果你想获取到的时间值更精确一些,System.nanoTime()优于System.currentTimeMillis()。如果jdk的版本>=jdk8,那么推荐统一使用Instant类。

 

证据

System.currentTimeMillis()   PK   new Date().getTime()

查看Date的源码会发现  new Date().getTime()本质上取的就是System.currentTimeMillis()的值,所不同的就是多new了一个对象,取的过程多了几次判断,线程中方法栈桢深了几层,因此当你仅仅是想获取当前的毫秒数时,完全没有必要脱了裤子放屁。

public class Date
    implements java.io.Serializable, Cloneable, Comparable<Date>
{
    private transient long fastTime;
    public Date() {
        this(System.currentTimeMillis());
    }
    public Date(long date) {
        fastTime = date;
    }
    public long getTime() {
        return getTimeImpl();
    }

    private final long getTimeImpl() {
        if (cdate != null && !cdate.isNormalized()) {
            normalize();
        }
        return fastTime;
    }
}

 

System.currentTimeMillis()   PK  System.nanoTime()

先来看一下System.currentTimeMillis()的jdk注释。返回以毫秒为单位的当前时间,注意:这个值的粒度依赖于底层的操作系统并有可能更大。举个栗子,很多操作系统的度量单位就是几十毫秒(tens of millisencodes).换言之,操作系统级别最小的时间度量单位有可能就是2毫秒,甚至10毫秒更高。

    /**
     * Returns the current time in milliseconds.  Note that
     * while the unit of time of the return value is a millisecond,
     * the granularity of the value depends on the underlying
     * operating system and may be larger.  For example, many
     * operating systems measure time in units of tens of
     * milliseconds.
     *
     * <p> See the description of the class <code>Date</code> for
     * a discussion of slight discrepancies that may arise between
     * "computer time" and coordinated universal time (UTC).
     *
     * @return  the difference, measured in milliseconds, between
     *          the current time and midnight, January 1, 1970 UTC.
     * @see     java.util.Date
     */
    public static native long currentTimeMillis();

再来看下System.nanoTime(),返回 JVM级别高精度的当前时间,以纳秒为单位。此方法只能用于测试已过的时间,并且与系统或者时钟无关。返回值是从某一固定时间开始计算中的纳秒数。

  /**
     * Returns the current value of the running Java Virtual Machine's
     * high-resolution time source, in nanoseconds.
     *
     * <p>This method can only be used to measure elapsed time and is
     * not related to any other notion of system or wall-clock time.
     * The value returned represents nanoseconds since some fixed but
     * arbitrary <i>origin</i> time (perhaps in the future, so values
     * may be negative).  The same origin is used by all invocations of
     * this method in an instance of a Java virtual machine; other
     * virtual machine instances are likely to use a different origin.
     *
     * <p>This method provides nanosecond precision, but not necessarily
     * nanosecond resolution (that is, how frequently the value changes)
     * - no guarantees are made except that the resolution is at least as
     * good as that of {@link #currentTimeMillis()}.
     *
     * <p>Differences in successive calls that span greater than
     * approximately 292 years (2<sup>63</sup> nanoseconds) will not
     * correctly compute elapsed time due to numerical overflow.
     *
     * <p>The values returned by this method become meaningful only when
     * the difference between two such values, obtained within the same
     * instance of a Java virtual machine, is computed.
     *
     * <p> For example, to measure how long some code takes to execute:
     *  <pre> {@code
     * long startTime = System.nanoTime();
     * // ... the code being measured ...
     * long estimatedTime = System.nanoTime() - startTime;}</pre>
     *
     * <p>To compare two nanoTime values
     *  <pre> {@code
     * long t0 = System.nanoTime();
     * ...
     * long t1 = System.nanoTime();}</pre>
     *
     * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
     * because of the possibility of numerical overflow.
     *
     * @return the current value of the running Java Virtual Machine's
     *         high-resolution time source, in nanoseconds
     * @since 1.5
     */
    public static native long nanoTime();

最后一个,优先使用Instant。 JDK8对时间 api,进行了较大的升级改造。Instant屏蔽了jdk8之前时间api的一些问题。

推荐使用:

Instant begin = Instant.now();

Duration.between(begin, Instant.now()).toMillis()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值