全面解析Java日期时间API


全面解析Java日期时间API

文章插图
 
时区
  • GMT(Greenwich Mean Time):格林尼治时间,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间 。
  • UTC(Universal Time Coordinated):统一协调时间,其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间,标准 UTC 时间格式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX 。
格林尼治时间已经不再被作为标准时间使用,UTC 是最主要的世界时间标准 。
JAVA提供了获取当前时间的方法
  • System.currentTimeMillis(),返回当前时间,以毫秒为单位,表示的就是当前时刻至 1970-01-01 00:00:00.000 的毫秒差值 。返回的long值可以用来初始化java.util.Date, java.sql.Date, java.sql.Timestamp和java.util.GregorianCalendar对象 。
  • System.nanoTime(),返回一个时间值(系统计时器的当前值),精确到纳秒 。它是由 JVM 提供的一个时间,主要用来精确衡量两个时间段之间的时间
例如,要测量一些代码需要执行多长时间,实现如下,
long startTime = System.nanoTime();//...the code being measuredlong estimatedTime = System.nanoTime() - startTime;
时间粒度
事实上System.currentTimeMillis()方法的时间粒度是大于1毫秒的 。如果你反复执行这个方法,你会发现短时间内得到的结果是相同的,随后又突然在某一次结果增加了几十毫秒(也可能更多) 。这是很正常的,毕竟这个方法肯定不是世界上最精密的计时器 。
旧的时间API
旧的时间API存在诸多问题,例如
  • Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义 。
  • java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理 。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计 。
  • 对于时间、时间戳、格式化以及解析,并没有一些明确定义的类 。对于格式化和解析的需求,我们有java.text.DateFormat抽象类,但通常情况下,SimpleDateFormat类被用于此类需求 。
  • 所有的日期类都是可变的,因此他们都不是线程安全的,这是Java日期类最大的问题之一 。
  • 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题 。
java.util.Date类
java.util.Date类用于封装日期及时间信息,一般仅用它显示某个日期,不对他作任何操作处理,作处理推荐用Calendar类,计算方便 。以下已过时的方法没有列出,可自行查看jdk文档
构造方法
  • Date() :分配 Date对象并初始化此对象,以表示分配它的时间(精确到毫秒) 。
  • Date(long date):分配 Date对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数 。
//1、使用Date类获取当前系统时间Date date = new Date();System.out.println(date);//由于Date类覆盖了toString()方法,所以可以直接输出Date类型的对象//输出结果为Fri May 31 10:51:18 GMT+08:00 2019/*给Date设置年份需要减去 1900*输出结果Tue Jul 01 00:00:00 GMT+08:00 3919*原来这里存在一个起始年份 1900,实际年份是要在你的年份参数上加上个起始年份 。*/Date date1 = new Date(2019,5,31);System.out.println(date1);//2.分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数 。Date date2 = new Date(System.currentTimeMillis());//参数为19701月1日以来的毫秒数Date date3 = new Date(1559284293556l); //long类型要加lSystem.out.println(date2);System.out.println(date3);//其他Date方法摘要可查看apiCalendar类与GregorianCalendar
java.util.Calendar类用于封装日历信息,其主作用在于其方法可以对时间分量进行运算 。Calendar类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法 。
由于Calendar类是抽象类,且Calendar类的构造方法是protected的,所以无法使用Calendar类的构造方法来创建对象,API中提供了getInstance方法用来创建对象 。
Java只提供java.util.GregorianCalendar这一种java.util.Calendar的实现类,可以直接新建出来使用:
Calendar calendar = new GregorianCalendar();//新建出来的calendar默认时间为当前时间,或者说创建出这个对象的时间 。


推荐阅读