为什么Java日历说这个月的第一个星期四是第5周?



我想弄清楚如何在一周的特定日子发出警报。下面是打印我期望的示例代码:

  Calendar calendar = Calendar.getInstance();
  calendar.set(Calendar.WEEK_OF_MONTH, 1);
  System.out.println("Week of month: " + calendar.get(Calendar.WEEK_OF_MONTH)); // Week of month: 1

但是当我把这个添加到代码中时,我得到了一个我不理解的结果:

  Calendar calendar = Calendar.getInstance();
  calendar.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
  calendar.set(Calendar.WEEK_OF_MONTH, 1);
  System.out.println("Week of month: " + calendar.get(Calendar.WEEK_OF_MONTH)); // Week of month: 5

我想在特定的一周的特定的一天设置一个闹钟。今天的日期是2013年6月15日。有人能给我解释一下吗?对于我正在做的事情来说,没有足够的时间,所以我需要使用常规的Java库来完成这项工作。谢谢你的帮助。

编者按

上面的代码将根据运行的日期返回不同的结果,因为Calendar.getInstance()返回一个设置为当前时间的Calendar。对于独立于当前时间的问题的说明,使用以下命令:

DateFormat dateFormat = DateFormat.getDateInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(1371294000000L);
System.out.println(dateFormat.format(calendar.getTime()));
calendar.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
System.out.println(dateFormat.format(calendar.getTime()));
calendar.set(Calendar.WEEK_OF_MONTH, 1);
System.out.println("Week of month: " + calendar.get(Calendar.WEEK_OF_MONTH)); 
System.out.println(dateFormat.format(calendar.getTime()));

输出如下内容(至少如果您的默认语言环境使用的是公历):

Jun 15, 2013
Jun 13, 2013
Week of month: 5
May 30, 2013

Java Calendar默认是宽大的。如果你将它设置为1月32日,它会将其转换为2月1日。此外,"week"的定义是特定于地区的,有点令人困惑。这在上面链接到的javadoc中有详细的解释。

在您的特定情况下(或至少在我的Locale中),一周被定义为从周日开始,"6月的第一周"被定义为包括6月1日在内的周日到周六期间。2013年6月1日是星期六,是2013年第22周的最后一天。星期日,2013年6月2日,是6月第二周的第一天,而不是第一周的第二天。

由于6月的第1周没有星期四,因此宽大的日历将DAY_OF_WEEK, THURSDAY解释为2013年第22周的星期四,即2013年5月30日,即5月的第5周,因此您在输出中得到5而不是1。

要设置六月的第一个星期四,您需要:

 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.MONTH, Calendar.JUNE);
 calendar.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
 calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);

DAY_OF_WEEK_IN_MONTH可能有点令人困惑。您可以将它与DAY_OF_WEEK一起使用,以指定希望在那个月的哪一天出现。因此,当DAY_OF_WEEK被设置为星期四时,DAY_OF_WEEK_IN_MONTH, 1是该月的第一个星期四,DAY_OF_WEEK_IN_MONTH, 2是该月的第二个星期四,以此类推。比起一个月的第一周由哪些天构成,这与地区的特殊性或(错误的)解释要少得多。

最新更新