Java日历 - 设置day_of_week后日期不可预测

Jes*_*run 12 java

我在JUnit测试中有以下代码,这似乎在上周工作失败了本周:

Calendar cal = Calendar.getInstance();
cal.set(2011, Calendar.JULY, 12);
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY); // push the date to 15
System.out.println(cal.get(Calendar.DATE));
Run Code Online (Sandbox Code Playgroud)

正如您可能从我的评论中推断出的那样,因为12日是星期二,所以在将DAY_OF_WEEK设置为星期五后,我预计日期为15.但是,打印的值为22,导致测试失败.

但是,如果我按如下方式更改代码,并添加一个额外的调用来获取:

Calendar cal = Calendar.getInstance();
cal.set(2011, Calendar.JULY, 12);
System.out.println(cal.get(Calendar.DATE));
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY); // push the date to 15
System.out.println(cal.get(Calendar.DATE));
Run Code Online (Sandbox Code Playgroud)

我得到了我期望的输出,12和15.

有人可以解释一下发生了什么,为什么这个测试上周有效?

Aff*_*ffe 19

首先要理解的是,Month + Day + DayOfWeek对日历没有任何意义.日历将根据日期计算日期的真实值

年+月+日

要么

年+月+周W_K_MONTH + DAY_OF_WEEK

(或其他一些组合,如年份+一年中的某一天等)所以Date + DayOfWeek本身并不意味着它.

要理解的第二件事是,当您设置Java日历时,它实际上不会重新计算绝对时间或更新相关字段,直到强制计算的操作发生.

第一次设置后,日历处于冲突状态.月份和日期说它是7月12日,但是"月中的一周"和"星期几"仍然表示它是今天,无论今天是什么.然后,您将周日设置为星期五.所以今天的月份和日期说是7月12日,但是"一个月的一周"和"一周的一天"字段表示它是'这个'周的星期五.

日历的规则说最近设置的字段在出现冲突时"获胜",因此本周五结合的星期和星期几用于计算其他字段.

在中间插入一个"修复"它,因为它强制将日历的整个内部状态重新计算到7月12日星期二,然后再设置为星期五,因此没有内部冲突.通过在您将星期几设置为星期五之前重新计算,将"月中的一周"设置为包含7月12日的一周.

编辑:很抱歉在两天后进行更改,在旧的浏览器标签中注意到这一点,并认为我会扩展为未来的googlers的希望帮助:

乔恩在评论中工作的原因是他住在伦敦.他的电脑认为星期一星期开始.所以当被问到'这个'周的星期五时,7月17日星期日被问到时,它仍然在7月15日回复.我提出这个问题是因为在不同的语言环境中,一周的第一天不同只是尝试在日历中使用WEEK_OF字段的另一种方式.

  • 这提出了一个额外的问题,为什么我不在床上:/ (2认同)