System.nanoTime与System.currentTimeMillis的用法分析及区别

System.nanoTime的介绍

public static long nanoTime(): 返回最准确的可用于系统计时的时间值,以毫微秒即纳秒为单位。

此方法只能用于测量已过去的时间,与系统或钟表时间表示的时间概念无关。
返回值表示从某一固定但任意的时间开始计算的毫微秒数(也可以从将来某一时刻算起,所以该值可能为负值)。此方法提供毫微秒的精度,但不是必要的毫微秒的准确度。它对于值的更改频率没有作出保证。
在取值范围大于约 292 年的连续调用时,会由于数字溢出,将无法准确计算已过的时间(Long最大值9223372036854775807,该数量的纳秒即9223372036秒,约为292年)。

例如,测试某些代码执行的时间长度:

1
2
3
4
5
6
//由于选取比较的时间点任意,startTime每次都不同

long startTime = System.nanoTime();
System.out.println(startTime);      //171258913345100
long duringTime = System.nanoTime() - startTime;
System.out.println(duringTime);     //421500

System.currentTimeMillis的介绍

public static long currentTimeMillis(): 返回以毫秒为单位的当前时间。

System.currentTimeMillis返回的是从1970.01.01 零点开始到现在的时间,精确到毫秒,我们也可以根据System.currentTimeMillis来计算当前日期、星期几等,可以方便的与Date进行转换。

1
2
3
4
5
6
7
//时间戳转String日期
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = dateformat.format(System.currentTimeMillis());

//String日期转时间戳
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long time = dateformat.parse("2016-09-02 23:02:17").getTime();

注意:测试时候可能会出现当前获取的毫秒值转换为日期后,再转为毫秒值时候 与前者不一致,这个是因为获取的是毫秒值,而转换为日期后是以秒为单位了,所以转换后才会出现这种情况。 如果想要解决那么就得在时间格式化的时候写成 :
SimpleDateFormat dateformat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);

总结分析

区别1:

System.nanoTime()返回的是纳秒,数值可能是任意数,甚至可能是负数
nanoTime主要用途是衡量一个时间段的长短,比如一段代码执行所用的时间,获取数据库连接所用的时间,网络访问所用时间等。返回值本身则没有什么意义,因为它基于的时间点是随机的。

System.currentTimeMillis()返回的是毫秒,是自1970年01月01日0时起计算的毫秒数,若系统时间固定则方法返回值也是一定的
在开发过程中,获取时间戳,可以使用new Date().getTime()去获取,
但是源码显示:public Date() { this(System.currentTimeMillis()); }
new Date()所做的事情其实就是调用了System.currentTimeMillis()。如果仅仅是需要毫秒数,那么完全可以使用System.currentTimeMillis()去代替new Date()。

currentTimeMillis是一个时钟,而nanoTime是一个计时器,时钟可以用来表示时间、计算时间差,但是计时器只能用来计算时间差,当然优点是精确度高。

区别2:
currentTimeMillis是基于系统时间的,如果你在程序执行期间更改了系统时间则结果就会出错,而nanoTime是基于CPU的时间片来计算时间间隔的,无法人为干扰。

课外补充

1纳秒=1000 皮秒 
1纳秒 =0.001 微秒
1纳秒=0.000001 毫秒
1纳秒=0.00000 0001秒