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

问题描述 投票:0回答:2

我想弄清楚如何在一周中的特定一天发出闹钟。 这是打印我期望的示例代码:

  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 日。有人可以向我解释一下吗? Joda 时间不适用于我正在做的事情,因此我需要使用常规 Java 库来完成这项工作。 感谢您的帮助。

编者注

上面的代码将根据运行日期返回不同的结果,因为

Calendar.getInstance()
返回设置为当前时间的日历。 要说明与当前时间无关的问题,请使用:

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
2个回答
5
投票
默认情况下,

Java Calendarlenient。如果您将其设置为 1 月 32 日,则会将其转换为 2 月 1 日。此外,“周”的定义是特定于区域设置的,并且有点令人困惑。 上面链接的 JavaDocs 对此进行了详细解释。

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

由于 6 月的第 1 周没有星期四,lenient 日历将

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
是该月的第二个星期四,等等。这不太特定于区域设置或容易(错误)解释,那么什么天构成该月的第一周。


0
投票

避免遗留日期时间类

存在严重缺陷的遗留日期时间类已被 JSR 310 中定义并内置于 Java 8 及更高版本中的现代 java.time 类所取代。

切勿使用

Date
Calendar
Timestamp
SimpleDateFormat

java.time

确定今天的日期。这需要一个时区。对于任何给定时刻,全球各地的时间和日期都会因时区而异。

ZoneId z = ZoneId.of( "America/Edmonton" );

获取今天日期的

LocalDate

LocalDate today = LocalDate.now( z ) ;

获取该日期当月的第一个星期四。使用

TemporalAdjusters
(复数)类中的 TemporalAjduster。

© www.soinside.com 2019 - 2024. All rights reserved.