日期:2014-05-20  浏览次数:20706 次

请教Calendar类的roll()方法
运行了一下,结果跟API写得不符合,请高手帮忙找找错...

这是我测试的代码:
package com.ocjp.g11n;
import java.util.*;

public class CalendarTest {
 public static void main(String[] args) {
 Calendar c = Calendar.getInstance();
 c.set(1999,8,31);
//  System.out.println(c.getTime());
 c.roll(Calendar.MONTH, 13); //API写的,输出应该是1999,9,30.理由是roll()传的参数是MONTH,roll()不会调整比当前参数大的字段,也就是不调整YEAR;比当前参数小的字段,本例中为DAY,如果超出范围了,取最接近的值;所以这行代码,在原来8月的基础上+13,月份应该变成9,但9月没有31天,就自动调整为30;年份不变,为什么我运行的结果不对呢?
 System.out.println(c.getTime());
 c.add(Calendar.DATE, 10);
 System.out.println(c.getTime());
 }
}

输出为:
Mon Nov 01 23:35:00 EST 1999
Thu Nov 11 23:35:00 EST 1999

为什么我测试的结果跟API写的不一样?我把API内容COPY如下:

Example: Consider a GregorianCalendar originally set to August 31, 1999. Calling add(Calendar.MONTH, 13) sets the calendar to September 30, 2000. Add rule 1 sets the MONTH field to September, since adding 13 months to August gives September of the next year. Since DAY_OF_MONTH cannot be 31 in September in a GregorianCalendar, add rule 2 sets the DAY_OF_MONTH to 30, the closest possible value. 
Calendar

------解决方案--------------------
原因是,java/javascript的月,都是基于0的
也就是1月=0,12月=11,参考java.util.Calendar#JANUARY

你set(1999,8,31)最终设置的是1999年9月31日,也就是10月1日,于是...
------解决方案--------------------
代码分析:

java.text.SimpleDateFormat df=new java.text.SimpleDateFormat("yyyy-MM-dd");
 Calendar c = Calendar.getInstance();  
 c.set(1999, 7, 31); //1999-8-31
 
 System.out.println("=======add()================");
 System.out.println("1、规则第一条:");
 System.out.println("当被修改的字段超出它可以的范围时,那么比它大的字段会自动修正。");
 System.out.println("2、规则第二条:");
 System.out.println("当被修改的字段超出它可以的范围时,那么比它大的字段不会被修正。");
 System.out.println("****************************");
 
 
 //规则1: 没有超出范围,不用改变大的字段(年份不变)
 c.add(Calendar.MONTH, 1); //1999-9-31 => 1999-10-1,对吗?
//规则2:比其小的字段(日期改变),变化最小值,为30即可
 System.out.println(df.format(c.getTime())); //结果是 1999-9-30
 
 //再如
 c.set(1999,7,31); //1999-8-31
//规则1:超出范围,改变大的字段(年份为2000年) 2000-9-31  9月没有31
//规则2:比其小的字段(日期改变),变化最小值,为30即可 ==> 变成 2000-9-30
 c.add(Calendar.MONTH, 13);   
 System.out.println(df.format(c.getTime())); //结果是 2000-9-30
 
 
 System.out.println("===========Roll()============");
 System.out.println("规则只有第二条:");
 System.out.println("当被修改的字段超出它可以的范围时,那么比它大的字段不会被修正。");
 System.out.println("*****************************");