深入理解Java常用类-----时间日期

除了String这个类在日常的项目中比较常用之外,有关时间和日期的操作也是经常遇到的,本篇就讲详细介绍下Java API中对时间和日期的支持。其实在Java 8之前时间日期的API并不是很好用,以至于人们在项目中大多使用的是一个第三方库 Joda-Time,当然Java 8 吸收了该库的大部分优点,改进了相关API,现在的时间日期处理接口相对以前来说是好用很多,本篇也将学习下这个优秀的第三方库。下面是本篇主要涉及内容:

古老的Date类

处理年月日的年历类Calendar

格式化字符串和日期对象的DateFormat格式转换类

好用的SimpleDateFormat实现类

Joda-Time库

一、古老的Date类
     Date这个类自jdk1.0开始就被设计出来, 从它的源代码中我们也是可以看出来,Date类曾经扮演过很重要的角色,jdk早期的版本中有关日期和时间的操作几乎都是由Date类完成的,下面我们一起看看它的源码:

private transient long fastTime;

首先Date中有封装一个long类型的变量,这个变量是整个时间日期操作的对象,也就是我们使用该变量代表时间和日期。下面说明它是如何表示时间和日期的。所有计算机中的时间都是用一个整数表示的,该整数的值代表的是距离格林尼治标准时间(1970年1月1日0时0分0秒)的毫秒数,也就是说fastTime值为1000的时候代表时间为1970年1月1日0时0分1秒。至于为什么是这个时间,由于种种历史原因大家也可以去了解下,此处不再赘述。

由于该类中大部分方法都被注解了@Deprecated,已经不再推荐使用了,所以接下来我们主要还是看看其中还保留着的方法。只剩下两个构造方法:

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

只推荐使用上述两个构造方法来构造我们的Date对象,一个是默认无参构造器(内部调用本地函数获取系统当前时间计算与标准时间的毫秒差值),另一个则需要手动传入一个毫秒值构造Date对象。

剩下的则主要是一些获取和设置fastTime的函数,以及比较日期大小的函数,其他的都被注解了,至于上述这些函数,代码相对简单此处不再赘述。

二、处理年月日的年历类Calendar
     以前我们是可以使用Date来处理日期年月日的,但是由于该类不支持国际化等原因,现在其中大部分方法被注解,不再推荐使用,现在的Date类更像是代表着某一个时刻的对象,而处理年月日的这种转换则完全交给了Calendar类处理。所以Calendar目前是日期时间处理中的核心类,接下来我们看看其中源码:

//和Date一样封装了毫秒属性 protected long time; protected int fields[]; //封装了十七个静态常量 public final static int ERA = 0; public final static int YEAR = 1; public final static int MONTH = 2; public final static int WEEK_OF_YEAR = 3; ......... public final static int DST_OFFSET = 16;

在Calendar的内部封装了17个静态常量,这些常量将会作为索引用来检索fields属性,例如:fields[YEAR]将返回当前毫秒值对应的日期时间的年份部分,fields[MONTH]将返回的是月份部分的值等等。至于这些值是哪里来的,等我们介绍到后续源码的时候再说明,此处只需要理解这些常量的作用即可。

该类是抽象类,我们使用工厂方法获取该类实例:

public static Calendar getInstance() { return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT)); } public static Calendar getInstance(TimeZone zone) { return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT)); } public static Calendar getInstance(Locale aLocale) { return createCalendar(TimeZone.getDefault(), aLocale); } public static Calendar getInstance(TimeZone zone, Locale aLocale) { return createCalendar(zone, aLocale); }

主要有四个方法用于创建Calendar实例,其实内部调用的是同一的方法只是传入的参数的值不同。创建一个Calend 实例需要两个参数,一个是TimeZone时区,另一个是Locale语言国家。因为每个国家或地区他们表示时间的形式是不一样的,所以我们需要通过这两个参数确定具体需要使用的格式,当然是以本地时间作为fastTime的值的,如果我们没有指定时区和国家语言,那么将会默认使用本机系统信息。接下来我们看如何通过获取到Calendar实例完成对日期时间进行计算。

我们有获取和设置内部代表毫秒的time属性:

public final Date getTime() { return new Date(getTimeInMillis()); } public void setTimeInMillis(long millis){}

也有获取上述介绍的17中属性的方法:

public int get(int field) { complete(); return internalGet(field); }

其中complete方法就是调用了本地函数完成对fields属性中没有值的元素赋值。 调用internalGet方法其实就是调用的fields[field],为我们返回指定属性的结果值。我们可以看个例子:

public static void main(String[] args){ Calendar calendar = Calendar.getInstance(); System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH)); System.out.println(calendar.get(Calendar.AM_PM)) }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzjgxx.html