Java中处理日期的常用类
(2012-03-05 12:12:06)
标签:
java处理日期datecalendarit |
Java中处理日期最常用的类是Date类和Calendar类,掌握这两个类的用法在项目中处理起日期来就轻松多了。下面是这个类的详细用法。
一.Date类
Java提供了Date类来处理日期、时间(此处的Date是指java.util包下的Date类,而不是java.sql包下的Date类),这个Date类从JDK1.0起就开始存在了。但正因为它历史悠久,所以它的大部分构造器、方法都已经过时,不再推荐使用了。
Date类提供了6个构造器,但其中4个已经被Deprecated(Java不再推荐使用,使用不再推荐的方法时编译器会提出警告信息,并导致程序性能、安全性等方面的问题),剩下的两个构造器分别为:
Ø
Millis()获得long整数作为日期参数。
Ø
与Date构造器相同的是,Date对象的大部分方法也被Deprecated了,剩下为数不多的几个方法:
Ø
Ø
Ø
Ø
Ø
Ø
下面程序示范了Date类的用法:
public
{
public
{
Date
//获取当前时间之后100ms的时间
Date
System.out.println(d2);
System.out.println(d1.compareTo(d2));
System.out.println(d1.before(d2));
}
}
因为Date类的很多方法已经被不推荐使用了,所以Date类的功能已经被大大削弱了,例如所有对时间进行加减运算,获取指定Date对象里年、月、日的方法都已被Deprecated。如果需要对日期进行这些运算,应该使用Calendar工具类。
二.
因为Date类的设计上存在一些缺陷,所以Java提供了Calendar类来更好地处理日期和时间。Calendar是一个抽象类,它用于表示日历。
Calendar本身是一个抽象类,它是所有日历类的模板,并提供了一些所有日历通用的方法,但它本身不能直接实例化。程序只能创建Calendar子类的实例,Java
当然,也可以创建自己的Calendar子类,然后将它作为Calendar对象使用(这就是多态),在IBM的alphaWorks站点(http://www.alphaworks.ibm.com/tech/calendars)上,IBM的开发人员实现了多种日历。在Internet上,也有对中国农历的实现。
Calendar类是一个抽象类,所以不能使用构造器来创建Calendar对象。但它提供了几个静态getInstance方法来获取Calendar对象。这些方法根据TimeZone,Locale类获取特定Calendar,如果不指定TimeZone、Locale,则使用默认的TimeZone、Locale来创建Calendar。
Calendar与Date都是表示日期的工具类,它们直接可以自由转换,如下代码所示:
//创建一个默认的Calendar对象
Calendar
//从Calendar
Date
//通过Date对象获得对应的对象中,
//因为Calendar/GregorianCalendar没有构造函数可以接受Date对象
//所以必须先获得一个Calendar实例,然后调用其setTime方法
Calendar
calendar2.setTime(date);
Calendar提供了大量访问、修改时间日期的方法,Calendar大致有如下几个常用方法:
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
上面很多方法都需要一个int类型的field参数,field是Calendar类的静态属性,如Calendar.YEAR、Calendar.MONTH等,分别代表了年、月、日、小时、分钟、秒、微秒等时间字段。Calendar.MONTH字段需要注意:月份的起始值为0而不是1,所以要设置8月时,用7而不是8。
如下程序示范了Calendar类的常规用法:
public
{
public
{
Calendar
//取出年
System.out.println(c.get(YEAR));
//取出月份
System.out.println(c.get(MONTH));
//取出日
System.out.println(c.get(DATE));
//分别设置年、月、日、小时、分钟、秒
c.set(2003
System.out.println(c.getTime());
//将Calendar的年前推1年
c.add(YEAR
System.out.println(c.getTime());
//将Calendar的月前推8个月
c.roll(MONTH
System.out.println(c.getTime());
}
}
上面程序中粗体字代码示范了Calendar类的用法,Calendar可以很灵活地改变它对应的Date。
Calendar类还有如下几个注意点。
(1).add与roll的区别
add(int
add(int
Ø
Calendar
cal1.set(2003,
cal1.add(MONTH,
Ø
Calendar
cal1.set(2003,
//因为进位到后月份改为2月,2月没有31日,自动变成29日
cal1.add(MONTH,
上面的例子,8-31就会变成2-29。因为MONTH的下一级字段是DATE,从31到29改变最小。所以上面2003-8-23的MONTH字段增加6后,不是变成2004-3-2,而是变成2004-2-29。
roll的规则与add的处理规则不同:当被修改的字段超出它允许的范围时,上一级字段不会增大。
Calendar
cal1.set(2003,
//MONTH字段“进位”,但YEAR字段并不增加
cal1.roll(MONTH,
下一级字段的处理规则与add相似:
Calendar
cal1.set(2003,
//
cal1.roll(MONTH,
(2).设置Calendar的容错性
当我们调用Calendar对象的set方法来改变指定时间字段上的值时,有可能传入一个不合法的参数,例如为MONTH字段设置13,这将会导致怎样的后果呢?看如下程序:
public
{
public
{
Calendar
//结果是YEAR字段加1,MONTH字段为1(二月)
cal.set(MONTH
System.out.println(cal.getTime());
//关闭容错性
cal.setLenient(false);
//导致运行时异常
cal.set(MONTH
System.out.println(cal.getTime());
}
}
上面程序①、②两处的代码完全相似,但它们运行的结果不一样:①处代码可以正常运行,因为设置MONTH字段的值为13,将会导致YEAR字段加1。②处代码将会导致运行时异常,因为设置的MONTH字段值超出了MONTH字段允许的范围。关键在于程序中粗体字代码行,Calendar提供了一个setLenient用于设置它的容错性,Calendar默认支持较好容错性,通过setLenient(false)可以关闭Calendar的容错性,让它进行严格的参数检查。
(3).set方法延迟修改
set(f,
下面程序演示了set方法延迟修改的效果:
public
{
public
{
Calendar
cal.set(2003
//下面代码输出10月1日
//System.out.println(cal.getTime());
//设置DATE字段为5
cal.set(DATE
System.out.println(cal.getTime());
}
}
上面程序中创建了代表2003-8-31的Calendar对象,当把这个对象的MONTH字段加1后应该得到2003-10-1(因为9月没有31日),如果程序在①处代码输出当前Calendar里的日期,也会看到输出2003-10-1,③处输出2003-9-5。
如果程序将①处代码注释起来,因为Calendar的set方法具有延迟修改的特性,即Calendar实际上并未计算真实的日期,它只是使用内部成员变量表记录MONTH字段被修改为8,接着程序设置DATE字段值为5,程序内部再次记录DATE字段为5——就是9月5日,因此看到③处输出2003-9-5。
(参考资料:《疯狂Java讲义》)