首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

请问Calendar类的roll()方法

2013-07-04 
请教Calendar类的roll()方法运行了一下,结果跟API写得不符合,请高手帮忙找找错...这是我测试的代码:packag

请教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("*****************************");


 //使用 roll
 c.set(1999,7,31);//1999-8-31
 //没有规则1:roll 不改变年份,1999-21-31 -->1999-9-31  9月没有31
 //只有规则2:比其小的字段(日期改变),变化最小值,为30即可 ==> 变成 1999-9-30
 c.add(Calendar.MONTH, 13); 
 System.out.println(df.format(c.getTime())); //1999-09-30
 
 
 
 
 //你的代码 8 表示9月 1999-09-31,9月没有31,应该为1999-10-1 
 System.out.println("=======set()================");
 System.out.println("set() 会自动转换为合法的日期,如 set(1999,8,31) ");
 System.out.println("表示的是1999-09-31,9月没有31,应该为1999-10-1 ");
 System.out.println("*****************************");
 c.set(1999,8,31); // 1999-09-31 9月没有31 -->1999-10-1 
 System.out.println(df.format(c.getTime()));//1999-10-1
         c.roll(Calendar.MONTH, 11); //1999-21-01 ==>1999-09-01 
         System.out.println(df.format(c.getTime()));//1999-09-01 

热点排行