Java原本提供了Data和Calendar用于处理日期、时间的类,包括创建日期、时间对象,获取系统当前日期、时间等操作。但Date不仅无法实现国际化,而且它对不同属性也使用了前后矛盾的偏移量,比如月份与小时都是从0开始的,月份中的天则是从1开始的,年又是从1900开始的,而java.util.Calendar则显得过于复杂。从下面介绍可以看到Java对日期、时间处理不足。Java洗浴了Joda-Time库(一个被广泛使用的日期、时间库)的经验,提供了一套全新的日期时间库。
一、Date类
Java提供了Data类来处理日期、时间(此处的Date指的是java.util包下的Date类,而不会死java.sql包下的Date类),Date对象既包含日期,也包含时间。Date类送JDK1.0开始就存在了,但因为它历史悠久,所以它的大部分构造器、方法都已经过时了,不再推荐使用了。
Date类提供了6个构造器,其中4个已经Deprecated(Java不再推荐使用,使用不再推荐的构造器编译器会提出警告信息,并导致程序性能、安全性等方面的问题),剩下的两个构造器如下
①Date():生成一个代表当前日期时间的Date对象。该构造器在底层调用了System.currentTimeMillis()获得long整数作为日期参数。
②Date(long date):根据指定的long型整数来生成一个Date对象。该构造器的参数表示创建的Date对象和GMT 1970年1月1日00:00:00之间的时间差,以毫秒作为计时单位。
Date对象的大部分方法也已经Deprecated了,剩下为数不多的几个方法。
①boolean after(Date when):测试该日期是否在指定日期when之后。
②boolean before(Date when):测试该日期是否在指定日期when之前。
③long getTime():返回该时间对于的long型整数,即从GMT 1970-01-01 00:00:00之间的时间差,以毫秒作为单位。
④void setTime(long time):设置该Date对象的事件。
下面下程序示范了Date类的用法。
public class DateTest
{
public static void main(String[] args)
{
Date d1 = new Date();
//获取当前时间后100ms的事件
Date d2 = new Date(System.currentTimeMillis() + 100);
System.out.println(d2);
System.out.println(d1.compareTo(d2));
System.out.println(d1.before(d2));
}
}
总体来说,Date是一个设计相当糟糕的类,因此Java官方推荐尽量少用Date的构造器和方法。
二、Calendar类
因为Date类在设计上存在一些缺陷,所以Java提供了Calendar类来更好地处理日期和时间。Calendar是一个抽象类,它用于表示日历。
历史上有着许多种纪年方法,它的差异实在太大了。为了统一计时,全世界通常选择最普及、最通用的日历:Gregorian Calendar,也就是日常介绍年份时常用的“公元几几年”。
Calendar类本身是一个抽象类,它是所有日历类的模板,并提供了一些所有日历通用的方法;但它本身不能直接实例化,程序只能创建Calendar子类的实例,Java本身提供了一个GregorianCalendar类,一个代表格里高利日的子类。
Calendar类是一个抽象类,所以不能使用构造器来创建Calendar对象。但它提供了几个静态getInstance()方法来获取Calendar对象,这些方法根据TimeZone,Locale类来获取特定的Calendar,如果不指定Time、Locale,则使用了默认的TimeZone、Locale来创建Calendar。
Calendar与Date都是表示日期的工具类,它们直接可以自由转换。
//创建一个默认的Calendar对象
Calendar calendar = Calendar.getInstance();
//从Calendar对象中取出Date对象
Date date = calendar.getTime();
//通过Date对象获得对于的Calendar对象
//因为Calendar/GregorianCalendar没有构造函数可以接收Date对象
//所以必须先获得一个Calendar实例,然后调用其setTime方法
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);
Calendar类提供了大量访问、修改日期时间的方法。很多方法需要一个int类型的field,field是Calendar类的类变量,如Calendar.YEAR、Calendar.MONTH等分别代表了年、月、日、小时、分钟、秒等时间字段。
需要注意的是,Calendar.MONTH字段代表月份,月份的起始值不是1,而是0,所以要设置8月时,用7而不是8。如下程序示范了Calendar类的常规用法。
public class CalendarTest
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
//取出年
System.out.println(c.get(Calendar.YEAR));
//取出月份
System.out.println(c.get(Calendar.MONTH));
//取出日
System.out.println(c.get(Calendar.DATE));
//分别设置年、月、日、小时、分钟、秒
c.set(2003,10,23,12,32,23);//2003-11-23 12:32:23
System.out.println(c.getTime());
//将Calendar往前推1年
c.add(Calendar.YEAR, -1);//2002-11-23 12:32:23
//Calendar往前推8个月
c.roll(Calendar.MONTH, -8);//2002-03-23 12:32:23
System.out.println(c.getTime());
}
}