java - 如何使用 Java 找到一年中第 # 周的月份的所有周数?

标签 java date time dayofweek java-time

我希望构建一个函数,该函数返回一个数组,该数组包含一年中前几个月的所有周数,这些周数与某个特定月份的周数相同。

我将星期一用作一周的第一天,并将当月的第一个星期一作为本月的第一周。

输入:一年中的一周和一年。例如,27和2019。七月的第一周(7)。

输出:月份的周数组。例如,[2、6、10、14、19、23、27]。

我的尝试:

private void getResult(int weekYear)
{
    LocalDate date = LocalDate.now();
    final int weekNumber = 27;
    LocalDate newDate = date.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);
    int month = newDate.getMonthValue();;
        
    int weekMonth = LocalDate.from(newDate).get(WeekFields.ISO.weekOfMonth());
        
    System.out.println(newDate);
    System.out.println(month);
    System.out.println(weekMonth);
        
    ArrayList<Integer> list = new ArrayList<Integer>();
        
    for (int i = 1; i <= month; i++)
    {
        LocalDate tempDate = date.withYear(2019).withMonth(i).with(WeekFields.ISO.weekOfMonth(), weekMonth);
        int tempYear = LocalDate.from(tempDate).get(WeekFields.ISO.weekOfWeekBasedYear());
        list.add(tempYear);
    }
        
    list.forEach((e) -> System.out.print(e + " "));
}
int weekYear = 27;
getResult(weekYear);

我得到的:[1 6 10 14 18 23 27]。

我在找什么:我有两个问题:

  1. 第一个:获得的结果与预期的不同。我认为问题是由于我没有指定如何计算该月的第一周(该月的第一个星期一)。这样对吗?我该如何解决?
  2. 第二个:什么是更好的解决方案?

最佳答案

这里的关键是理解几点:

  1. 您以两种不同的方式计算周数。对于您使用 ISO 编号的一年中的一周:一年中的第一周至少包括新年的 4 天。对于一个月中的一周,您计算的是星期一(您可以说该月的第一周是该月的 7 天,而不是四天)。
  2. 周数可能并不总是存在。如果您的起点是该月的第 0 周或第 5 周,则前一个月可能没有该周。

the results obtained are different from those expected. I think the problem is due to the fact that I didn't specify how to calculate the first week of the month (first Monday of the month). Is it right? How can I solve that?

你是对的。要计算一个月中的星期一,您可以使用:

        LocalDate tempDate = date.withYear(2019)
                .withMonth(i)
                .with(ChronoField.DAY_OF_WEEK, DayOfWeek.MONDAY.getValue())
                .with(ChronoField.ALIGNED_WEEK_OF_MONTH, weekMonth);

(当然,DayOfWeek.MONDAY.getValue() 只是说1 的冗长方式,但更能表达意图,所以我更喜欢它。)

通过对代码的这种更改,输出是预期的:

2 6 10 14 19 23 27

关键是 ChronoField.ALIGNED_WEEK_OF_MONTH。一个月的对齐星期从该月的 1 号开始,并且无论星期几如何,始终为 7 天。第一个对齐的周是从该月的 1 号到 7 号,如果是从 8 号到 14 号,则第二个对齐的周是等等。因为我们已经将星期几设置为星期一,所以将对齐的星期设置为 1 给我们第一个星期一月份等

我们还没有完成。如果我将 weekNumber 设置为 40,我会得到:

2 6 10 14 14 23 27 27 36 41

我原以为 40 是列表中的最后一个数字,但它不在那里。 2019 年的第 40 周是从 9 月 30 日星期一到 10 月 6 日,所以如果我理解正确的话,你想要那些有第 5 周的月份的第 5 周。这让我们回到并非所有月份都有第 5 周的问题(因为他们没有 5 个星期一)。发生的事情是,由于我在星期二运行您的代码,因此以第 40 周的星期二(即 10 月 1 日)为起点,因此给了我每个月的第 1 周而不是第 5 周。

are there better solutions? Can you suggest one?

我真的不能。你得到的很好。

只是你没有使用 int weekYear 参数。您可能想用它代替 weekNumber 局部变量。在任何情况下,您都应该删除其中一个并使用另一个。

这个不相关的提示:您对 LocalDate.from(someLocalDate) 的使用是多余的,因为它只会再次为您提供相同的 LocalDate(相同的对象或相等的对象)一,我不知道也不关心)。在这些情况下只需使用 someLocalDate

关于java - 如何使用 Java 找到一年中第 # 周的月份的所有周数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57561272/

相关文章:

mysql 表选择未按逻辑列出

javascript - 无法使用 Javascript 将输入日期与当前日期进行比较

mysql - 获取日期和 null 之间的数据

javascript - 如何根据一天中的时间更改消息?

java - 两个单独的 getTime() 调用在不同时间返回相同的值

java - 使用 Calendar 和 SimpleDateFormat 将时间转换为 "HH:mm:ss"会增加 1 小时

java - Spring mvc 如何将请求参数绑定(bind)到Controller属性,如struts2

java - JPA - 按需多对一

java - 使用 Selenium 找出选择了哪个单选按钮(实现为 li)

java - 替换 forEach 并添加 collect