Java中处理日期的经常使用类

Java中处理日期最经常使用的类是Date类和Calendar类,掌握这两个类的用法在项目中处理起日期来就轻松多了。下面是这个类的详细用法。java

 

一.Datesql

Java提供了Date类来处理日期、时间(此处的Date是指java.util包下的Date类,而不是java.sql包下的Date类),这个Date类从JDK1.0起就开始存在了。但正由于它历史悠久,因此它的大部分构造器、方法都已通过时,再也不推荐使用了。安全

Date类提供了6个构造器,但其中4个已经被Deprecated(Java再也不推荐使用,使用再也不推荐的方法时编译器会提出警告信息,并致使程序性能、安全性等方面的问题),剩下的两个构造器分别为:函数

Ø Date():生成一个表明当前日期时间的Date对象。该方法在底层调用System.currentTime工具

Millis()得到long整数做为日期参数。性能

Ø Date(long date):根据指定的long型整数来生成一个Date对象。该构造器的参数表示建立的Date对象和GMT 1970年1月1日00:00:00之间时间差,以毫秒做为计时单位。测试

与Date构造器相同的是,Date对象的大部分方法也被Deprecated了,剩下为数很少的几个方法:spa

Ø boolean after(Date when):测试该日期是否在指定日期when以后。 设计

Ø boolean before(Date when):测试该日期是否在指定日期when以前。 对象

Ø int compareTo(Date anotherDate):比较两个日期的大小,后面的时间大于前面时间。 

Ø boolean equals(Object obj):当两个时间表示同一时刻时返回true。

Ø long getTime():返回该时间对应的long型整数,即从GMT 1970-01-01 00:00:00 到该Date对象之间时间差,以毫秒做为计时单位。 

Ø void setTime(long time):设置该Date对象的时间。 

 

下面程序示范了Date类的用法:

public class TestDate

{

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类的不少方法已经被不推荐使用了,因此Date类的功能已经被大大削弱了,例如全部对时间进行加减运算,获取指定Date对象里年、月、日的方法都已被Deprecated。若是须要对日期进行这些运算,应该使用Calendar工具类。

 

 

二. Calendar

由于Date类的设计上存在一些缺陷,因此Java提供了Calendar类来更好地处理日期和时间。Calendar是一个抽象类,它用于表示日历。

Calendar自己是一个抽象类,它是全部日历类的模板,并提供了一些全部日历通用的方法,但它自己不能直接实例化。程序只能建立Calendar子类的实例,Java 自己提供了一个GregorianCalendar类,一个表明GregorianCalendar的子类,它表明了咱们一般所说的公历。

固然,也能够建立本身的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 = Calendar.getInstance();

//从Calendar 对象中取出Date 对象

Date date = calendar.getTime();

//经过Date对象得到对应的对象中,

//由于Calendar/GregorianCalendar没有构造函数能够接受Date对象

//因此必须先得到一个Calendar实例,而后调用其setTime方法

Calendar calendar2 = Calendar.getInstance();

calendar2.setTime(date);

Calendar提供了大量访问、修改时间日期的方法,Calendar大体有以下几个经常使用方法:

Ø void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。

Ø int get(int field):返回指定日历字段的值。

Ø int getActualMaximum(int field):返回指定日历字段可能使用的最大值。例如月,最大值为11。

Ø int getActualMinimum(int field):返回指定日历字段可能拥有的最小值。例如月,最小值为0

Ø void roll(int field, int amount):与add方法基本相似,区别在于加上的value超过了该字段所能表示的最大范围后,也不会向上一个字段进位。

Ø void set(int field, int value):将给定的日历字段设置为给定值。 

Ø void set(int year, int month, int date):设置Calendar对象年、月、日三个字段的值。 

Ø void set(int year, int month, int date, int hourOfDay, int minute, int second):设置Calendar对象年、月、日、时、分、秒六个字段的值。

上面不少方法都须要一个int类型的field参数,field是Calendar类的静态属性,如Calendar.YEAR、Calendar.MONTH等,分别表明了年、月、日、小时、分钟、秒、微秒等时间字段。Calendar.MONTH字段须要注意:月份的起始值为0而不是1,因此要设置8月时,用7而不是8。

 

以下程序示范了Calendar类的常规用法:

public class TestCalendar

{

public static void main(String[] args) 

{

Calendar c = Calendar.getInstance();

//取出年

System.out.println(c.get(YEAR));

//取出月份

System.out.println(c.get(MONTH));

//取出日

System.out.println(c.get(DATE));

//分别设置年、月、日、小时、分钟、秒

c.set(2003 , 10 , 23 , 12, 32, 23); //2003-11-23 12:32:23

System.out.println(c.getTime());

//将Calendar的年前推1年

c.add(YEAR , -1); //2002-11-23 12:32:23

System.out.println(c.getTime());

//将Calendar的月前推8个月

c.roll(MONTH , -8); //2002-03-23 12:32:23

System.out.println(c.getTime());

}

}

上面程序中粗体字代码示范了Calendar类的用法,Calendar能够很灵活地改变它对应Date

 

 

Calendar类还有以下几个注意点。
(1).
add与roll的区别

add(int field, int amount)的功能很是强大,add 主要用于改变Calendar的特定字段的值。若是须要增长某字段的值,则让amount为正数;若是须要减小某字段的值,让amount为负数便可。

add(int field, int amount)有两条规则:

Ø 当被修改的字段超出它容许的范围时,会发生进位,即上一级字段也会增大。如:

Calendar cal1 = Calendar.getInstance();

cal1.set(2003, 7, 23, 0, 0 , 0); //2003-8-23

cal1.add(MONTH, 6); //2003-8-23 => 2004-2-23

Ø 若是下一级的字段也须要改变,那么该字段会修正到变化最小的值。如:

Calendar cal1 = Calendar.getInstance();

cal1.set(2003, 7, 31, 0, 0 , 0); //2003-8-31

//由于进位到后月份改成2月,2月没有31日,自动变成29日

cal1.add(MONTH, 6); //2003-8-23 => 2004-2-29

上面的例子,8-31就会变成2-29。由于MONTH的下一级字段是DATE,从31到29改变最小。因此上面2003-8-23的MONTH字段增长6后,不是变成2004-3-2,而是变成2004-2-29。

roll的规则与add的处理规则不一样:当被修改的字段超出它容许的范围时,上一级字段不会增大。

Calendar cal1 = Calendar.getInstance();

cal1.set(2003, 7, 23, 0, 0 , 0); //2003-8-23

//MONTH字段“进位”,但YEAR字段并不增长

cal1.roll(MONTH, 6); //2003-8-23 => 2003-2-23

下一级字段的处理规则与add类似:

Calendar cal1 = Calendar.getInstance();

cal1.set(2003, 7, 31, 0, 0 , 0); //2003-8-31

// MONTH字段“进位”后变成2,2月没有31日,YEAR字段不会改变,2003年2月只有28天

cal1.roll(MONTH, 6); //2003-8-23 => 2003-2-28

(2).设置Calendar的容错性

当咱们调用Calendar对象的set方法来改变指定时间字段上的值时,有可能传入一个不合法的参数,例如为MONTH字段设置13,这将会致使怎样的后果呢?看以下程序:

public class TestLenient

{

public static void main(String[] args) 

{

Calendar cal = Calendar.getInstance();

//结果是YEAR字段加1,MONTH字段为1(二月)

cal.set(MONTH , 13);   //

System.out.println(cal.getTime());

//关闭容错性

cal.setLenient(false);

//致使运行时异常

cal.set(MONTH , 13);   //

System.out.println(cal.getTime());

}

}

上面程序两处的代码彻底类似,但它们运行的结果不同:处代码能够正常运行,由于设置MONTH字段的值为13,将会致使YEAR字段加1。处代码将会致使运行时异常,由于设置的MONTH字段值超出了MONTH字段容许的范围。关键在于程序中粗体字代码行,Calendar提供了一个setLenient用于设置它的容错性,Calendar默认支持较好容错性,经过setLenient(false)能够关闭Calendar的容错性,让它进行严格的参数检查。


(3).set方法延迟修改

set(f, value)方法将日历字段f更改成 value,此外,它还设置了一个内部成员变量,以指示日历字段f已经被更改。尽管日历字段 f 是当即更改的,但该Calendar所表明时间却不会当即修改。可是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll()时才会从新计算日历的时间。这被称为set方法的延迟修改,采用延迟修改的优点是屡次调用set()不会触发屡次没必要要的计算(须要计算出一个表明实际时间的long型整数)。

下面程序演示了set方法延迟修改的效果:

public class TestLazy

{

public static void main(String[] args) 

{

Calendar cal = Calendar.getInstance();

cal.set(2003 , 7 , 31);  //2003-8-31
cal.set(MONTH , 8); //理论上应该是是10月1日,但其实是9月31日(不合法的日期)

//下面代码输出10月1日

//System.out.println(cal.getTime());    //

//设置DATE字段为5

cal.set(DATE , 5);    //

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讲义》)

相关文章
相关标签/搜索