为什么 java.util.Calendar return minimal WEEK_OF_MONTH 值为零?

Why does java.util.Calendar return minimal WEEK_OF_MONTH value as zero?

我正在尝试按如下方式设置 WEEK_OF_MONTH 字段的最小值:

calendar.set(WEEK_OF_MONTH, calendar.getActualMinimum(WEEK_OF_MONTH));

调用

calendar.getActualMinimum(WEEK_OF_MONTH)

returns 0

但是在 get* 操作的计算中,这个字段变成了 5。 此外,没有宽大模式,我得到

java.lang.IllegalArgumentException: WEEK_OF_MONTH: 0 -> 5 // or MONTH: 9 -> 8
    at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829)
    at java.util.Calendar.updateTime(Calendar.java:3393)
    at java.util.Calendar.complete(Calendar.java:2265)
    at java.util.Calendar.get(Calendar.java:1826)
    at Main.main(Main.java:19)

如果我设置 WEEK_OF_MONTH = 1,那么我会正确地得到它作为 1。

查看 example

任何人都可以澄清这种行为吗?提前致谢。

java.time

    Locale russia = Locale.forLanguageTag("ru-RU");
    WeekFields wf = WeekFields.of(russia);

    LocalDate date = LocalDate.now(ZoneId.of("Europe/Moscow"));
    int minimumWeekOfMonth = date.with(TemporalAdjusters.firstDayOfMonth()).get(wf.weekOfMonth());
    System.out.println("Minimum week of month: " + minimumWeekOfMonth);
    LocalDate dateInFirstWeekOfMonth = date.with(wf.weekOfMonth(), minimumWeekOfMonth);
    System.out.println("Date in first week of month: " + dateInFirstWeekOfMonth);

刚才运行这个片段时,我得到了以下输出:

Minimum week of month: 1
Date in first week of month: 2018-10-05

我假设您使用的是俄罗斯语言环境。俄罗斯使用国际周编号,其中星期一是一周的第一天,一年或一个月的第一周是包含一年或一个月中至少 4 天的第一周。所以 2018 年 10 月的第 1 周是从 10 月 1 日星期一到 10 月 7 日星期日。这反过来意味着这个月的最小周数是 1。从今天(星期五)开始并将月份的星期数设置为 1 给出星期几1,即 10 月 5 日星期五。

如果我从 9 月 12 日星期三开始,我会得到:

Minimum week of month: 0
Date in first week of month: 2018-08-29

9 月的第 1 周是从 9 月 3 日星期一到 9 月 9 日。这意味着 9 月 1 日和 2 日在第 0 周,因此 0 是 9 月的最小周数。当从星期三开始时,我将星期数设置为 0,我得到那个星期的星期三,恰好在八月:8 月 29 日。如果我们要求那个日期的星期几,我们得到 0 吗?

    System.out.println("Week of month: " + dateInFirstWeekOfMonth.get(wf.weekOfMonth()));

输出:

Week of month: 5

由于日期是八月,我们现在得到日期在八月的哪一周,恰好是第 5 周。

你的代码发生了什么?

在我看来 GregorianCalendar.getActualMinimum(Calendar.WEEK_OF_MONTH) 总是 returns 0。我无法理解这个观察结果。由于俄罗斯使用公历,GregorianCalendar 的实例是您真正从 Calendar.getInstance.

得到的

我不想打扰。正如我在评论中所说,日历 class 早已过时并且存在一系列设计问题,因此我建议您不要使用它。我当然更喜欢 java.time,现代 Java 日期和时间 API,任何时间。

Link

Oracle tutorial: Date Time 解释如何使用 java.time.