Calendar类的常见用法
1.代码示例
import java.util.*; //静态导入只能在JDK 1.5的编译环境下运行 import static java.util.Calendar.*; public class CalendarTest { 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(2016 , 10 , 23 , 12, 32, 23); //2016-11-23 12:32:23 System.out.println(c.getTime()); // 将Calendar的年前推1年 c.add(YEAR , -1); //2016-11-23 12:32:23 System.out.println(c.getTime()); // 将Calendar的月前推8个月 c.roll(MONTH , -8); //2016-03-23 12:32:23 System.out.println(c.getTime()); 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 System.out.println(cal1.getTime()); Calendar cal2 = Calendar.getInstance(); cal2.set(2003, 7, 31, 0, 0 , 0); // 2003-8-31 // 因为进位到后月份改为2月,2月没有31日,自动变成29日 cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29 System.out.println(cal2.getTime()); Calendar cal3 = Calendar.getInstance(); cal3.set(2003, 7, 23, 0, 0 , 0); //2003-8-23 // MONTH字段“进位”,但YEAR字段并不增加 cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23 System.out.println(cal3.getTime()); Calendar cal4 = Calendar.getInstance(); cal4.set(2003, 7, 31, 0, 0 , 0); //2003-8-31 // MONTH字段“进位”后变成2,2月没有31日, // YEAR字段不会改变,2003年2月只有28天 cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28 System.out.println(cal4.getTime()); } }
2.运行结果
2016
8
1
Wed Nov 23 12:32:23 CST 2016
Mon Nov 23 12:32:23 CST 2015
Mon Mar 23 12:32:23 CST 2015
Mon Feb 23 00:00:00 CST 2004
Sun Feb 29 00:00:00 CST 2004
Sun Feb 23 00:00:00 CST 2003
Fri Feb 28 00:00:00 CST 2003
3.代码说明
上面的代码示范了Calendar类的用法,Calendar可以很灵活地改变它对应的日期,该示例还演示了add方法和roll方法的区别:roll方法上一级字段不会进位,add方法上一级字段会进位。
Calendar类的容错性
1.代码示例
import java.util.*; import static java.util.Calendar.*; public class LenientTest { 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()); } }
2.运行结果
Wed Feb 01 20:42:00 CST 2017
Exception in thread "main" java.lang.IllegalArgumentException: MONTH
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2316)
at java.util.Calendar.updateTime(Calendar.java:2468)
at java.util.Calendar.getTimeInMillis(Calendar.java:1087)
at java.util.Calendar.getTime(Calendar.java:1060)
at LenientTest.main(LenientTest.java:18)
3.代码说明
Calendar有两种解释日历的模式:lenient模式和non-lenient模式。当Calendar处于lenient模式时,每个字段可接受超出它的范围;当Calendar处于non-lenient模式时,如果某个字段超出它的范围,程序将会抛出异常。
Calendar类的延迟修改
1.代码示例
import java.util.*; import static java.util.Calendar.*; public class LazyTest { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); cal.set(2003 , 7 , 31); //2003-8-31 // 将月份设为9,但9月31日不存在。 // 如果立即修改,系统将会把cal自动调整到10月1日。 cal.set(MONTH , 8); // 下面代码输出10月1日 //System.out.println(cal.getTime()); //① // 设置DATE字段为5 cal.set(DATE , 5); //② System.out.println(cal.getTime()); //③ } }
2.运行结果
Fri Sep 05 20:52:17 CST 2003
当放开①处代码,运行结果为下
Wed Oct 01 20:55:28 CST 2003
Sun Oct 05 20:55:28 CST 2003
3.代码说明
第③处的运行结果出现了不同的结果,很神奇。这是因为set()方法具有延迟修改的特性,即调用set()方法后Calendar实际并没有计算真实的日期,它只是使用内部成员变量记录MONTH字段被修改为8,接着程序设置DATA为5,程序内部再次记录DATE字段为5,就是9月5号。也就是说日期不会立即生效,直到下次调用get()、getTime()、getTimeInMillis()、add()、roll()才会重新计算时间。