new Date() 方法到底是获取什么时间

1、问题

java 中,new Date() 方法,获取的时间,究竟与当前的系统时间有什么关联?简单的时刻对应关系吗?

2、测试环境

  • 版本:jdk1.8.0_131
  • 主方法:
    public static void main(String[] args) throws InterruptedException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        int i = 0;
        while(true){
            System.out.println(i + "\t" +dateFormat.format( new Date() ) );
            i++;
            Thread.sleep(2000);
        }
    }
    

3、更新时间前

更新时间前

如上图所示,控制台输出的时间,与当前的系统时间一致。

4、更新时间后

保持该main方法一直在运行(不中断,一直在死循环中), 利用win10下的时间设置,更改系统时间后

更新时间后

如上图所示,控制台输出的时间,依然以更新时间前的为基准进行输出。

5、代码溯源

  • Date.java
package java.util;
public class Date
    /**
     * Allocates a <code>Date</code> object and initializes it so that
     * it represents the time at which it was allocated, measured to the
     * nearest millisecond.
     *
     * @see     java.lang.System#currentTimeMillis()
     */
    public Date() {
        this(System.currentTimeMillis());
    }
}
  • System.java
package java.lang;
public final class System {
    /**
     * 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();
}

6、分析

现象:JVM 在某一时刻,获取当前系统时间,同时内部维护该时间(或者说时刻更为准确),后续所有的时间操作,均以此时刻为基准。

由于不确定该时刻是JVM启动时,还是调用 new Date() 方法时;同时为了排除SimpleDateFormat相关方法故继续测试。

7、 继续测试1

更新测试主方法:

  • 要点:确定该时刻,同时排除SimpleDateFormat相关方法影响
public static void main(String[] args) throws InterruptedException {
    int i = 0;
    System.out.println("开始---" );
    Thread.sleep(10000);
    System.out.println("正式输出---" );
    while(true){
        System.out.println(i + "\t" + new Date() );
        i++;
        Thread.sleep(2000);
    }
}

说明:在Thread.sleep(10000) ,利用这段时间(10秒),更新系统时间

分析与继续测试

如上图,更新系统时间前,JVM进程已经启动。

分析与继续测试

如上图,利用这段时间(10秒),更新系统时间,此时,控制台输出的时间,以更新后的时间为基准进行输出。

8、继续测试2

现象:确定不是在 JVM启动时,内部维护该时刻。

但是依然不确定该时刻是调用 new Date() 方法时,还是调用 **System.currentTimeMillis()**时(参见 5、代码溯源 部分 ),故继续测试。

更新测试主方法:

  • 要点:在调用new Date()前,先行调用System.currentTimeMillis() 方法。
     public static void main(String[] args) throws InterruptedException {
        int i = 0;
        System.out.println("开始---" );
        System.out.println("当前系统时间对应的毫秒数:" + System.currentTimeMillis());
        Thread.sleep(10000);
        System.out.println("正式输出---" );
        while(true){
            System.out.println(i + "\t" + new Date() );
            i++;
            Thread.sleep(2000);
        }
    }
    

测试方法同上一部分,即:

利用这段时间(10秒),更新系统时间.

分析与继续测试

现象:该时刻不以调用 System.currentTimeMillis() 时为基准。

9、 分析

System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数,Date()其实就是相当于Date(System.currentTimeMillis()); 因为Date类还有构造Date(long date),用来计算long秒与1970年1月1日之间的毫秒差。得到了这个毫秒数,我们自己也可以算起现在的年月日周时

上述文字,参考:JAVA获取当前时间System.currentTimeMillis()_百度经验

10、猜想

new Date()第一次执行时,获取当前系统时间,同时内部维护该时间(或者说时刻更为准确),后续所有的时间操作,均以此时刻为基准。

继续查阅Date.java 方法

private transient long fastTime;

public Date() {
    this(System.currentTimeMillis());
}
public Date(long date) {
    fastTime = date;
}

猜你喜欢

转载自my.oschina.net/u/3136014/blog/1570053