我面临java.util.Calendar
的奇怪行为。
问题是当我在中间添加一个方法调用Calendar#getTime()
而不是我得到正确的结果但是当我直接获得本周的Dates
而没有调用Calendar#getTime()
时,它指的是 下周 而不是 当前周 。
请考虑以下代码段:
public class GetDatesOfWeek {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Calendar cal = Calendar.getInstance();
cal.set(1991, Calendar.DECEMBER, 11);
//System.out.println(cal.getTime());//LINE NO : 14
for(int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) {
cal.set(Calendar.DAY_OF_WEEK, i);
Date date = cal.getTime();
System.out.println(sdf.format(date));
}
}
}
当我取消注释行14
时,我得到以下输出:
Wed Dec 11 07:38:06 IST 1991
08-12-1991
09-12-1991
10-12-1991
11-12-1991
12-12-1991
13-12-1991
14-12-1991
但是当我评论该行并执行代码时,我会得到以下输出。
15-12-1991
16-12-1991
17-12-1991
18-12-1991
19-12-1991
20-12-1991
21-12-1991
请注意,在两种情况下,月份和年份字段都是正确的,但开始日期从08-12-1991
更改为15-12-1991
,因为我08-12-1991
正确。< / p>
我的问题:
答案 0 :(得分:5)
如果您在调试器中单步执行代码,您将看到cal
对象的内部变量发生了有趣的事情。
日历对象分别存储它所代表的时间和调整字段。在执行第12行之后,使用当前时间和没有调整字段构造cal对象,并将其内部变量isTimeSet
设置为true。这意味着存储的内部时间是正确的。
执行第13行会将isTimeSet
清除为false,因为现在需要通过调整字段调整内部时间,然后才能再次准确。这不会立即发生,而是等待拨打getTime()
或get(...)
,getTimeInMillis()
,add(...)
或roll(...)
。
第14行(如果未注释)强制使用调整字段重新计算内部时间,并再次将isTimeSet
变量设置为true。
第17行然后设置另一个调整字段,并再次取消设置isTimeSet
变量。
第18行根据第17行中设置的调整字段重新计算正确的时间。
解决方案:
将日期设置与星期几相结合时会出现问题。设置星期几时,将忽略日期设置,并将cal
对象中的当前日期用作起点。你恰好在15日开始一周,因为今天的日期是1991年12月12日和15日,是最接近1991年12月12日的星期日。
注意:如果您在一周内再次运行测试,则会得到不同的结果。
解决方案是致电getTimeInMillis()
或getTime()
以强制重新计算时间,然后再设置星期调整。
<强>测试强>
如果您不想再等一周再次测试,请尝试以下操作:
public class GetDatesOfWeek {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Calendar cal = Calendar.getInstance();
cal.set(2015, Calendar.AUGUST, 1); // adjust this date and see what happens
cal.getTime();
cal.set(1991, Calendar.DECEMBER, 11);
//System.out.println(cal.getTime());//LINE NO : 14
for(int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) {
cal.set(Calendar.DAY_OF_WEEK, i);
Date date = cal.getTime();
System.out.println(sdf.format(date));
}
}
}