Java 8 LocalDate:确定每月的星期几(第1,第2,第3等)

时间:2018-01-08 17:37:57

标签: java java-8 java-time dayofweek localdate

我正在试图弄清楚如何确定特定星期一是某个月的第一个,第二个,第三个还是第四个星期一。我已经想出了如何获得使用LocalDate类的下个星期一和月份的周。

LocalDate now = LocalDate.of(2018, 2, 1);
LocalDate nextMonday = now.with(next(DayOfWeek.MONDAY));
WeekFields weekFields = WeekFields.of(Locale.getDefault());
int week = nextMonday.get(weekFields.weekOfMonth());

上例中的情况,代码获取下一个星期一及其所在的星期。星期是2月的第二周,但是星期一不是第二个星期一,它是第一个星期一。对此的任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:8)

你不应该使用自己的算术。使用内置功能:

    int week = nextMonday.get(ChronoField.ALIGNED_WEEK_OF_MONTH);

使用代码中的日期产生:

1

这意味着你得到的星期一(2月5日)是这个月的第一个星期一。此外,您不需要任何WeekFields,因为该月的第一个星期一是该月的第一个星期一,无论哪一天是一周的第一天,或者一年中的几周如何编号。

日期算术通常很复杂且容易出错。这也意味着即使你最终得到正确的计算,读者也很难说服自己/你自己你的代码是正确的。因此,最好使用我们信任的内置功能进行测试,并使用解释性名称而不是1和7之类的数字。

您可能会对使用的字段称为ALIGNED_WEEK_OF_MONTH感到惊讶。将对齐的周数视为从本月1日开始的一周,无论是星期几,还是接下来的几周。 2018年2月,第一个对齐的一周从2月1日星期四到2月7日星期三。以下一致的星期从2月8日星期四,2月15日和2月22日开始。显然,本月的第一个星期一是在第1周,第二个星期一,在第2周对齐,等等。因此,它可以使用ALIGNED_WEEK_OF_MONTH

答案 1 :(得分:2)

修改:您应该接受Ole V. V的回答(ChronoField.ALIGNED_WEEK_OF_MONTH),而不是这个答案。

你可以弄清楚它是哪一天,除以7,然后加1:

LocalDate nextMonday = now.with(next(DayOfWeek.MONDAY));
int weekNo = ((nextMonday.getDayOfMonth()-1) / 7) +1;

例如,此代码:

LocalDate now = LocalDate.of(2018, 2, 1);
for(int i = 0; i < 10; i++) {
    now = now.with(next(DayOfWeek.MONDAY));
    int weekNo = ((now.getDayOfMonth()-1) / 7) +1;
    System.out.println("Date : " + now + " == " + weekNo);
}

打印出以下内容,我相信你想要的......

Date : 2018-02-05 == 1
Date : 2018-02-12 == 2
Date : 2018-02-19 == 3
Date : 2018-02-26 == 4
Date : 2018-03-05 == 1
Date : 2018-03-12 == 2
Date : 2018-03-19 == 3
Date : 2018-03-26 == 4
Date : 2018-04-02 == 1
Date : 2018-04-09 == 2

答案 2 :(得分:0)

您可以尝试重复从日期减去一周,直到月份发生变化。那么你做的次数就是原始日期'本月的第X天'。

编辑:一些代码。

LocalDate now = LocalDate.of(2018, 2, 1);

int i = 0;
Month originalMonth = now.getMonth();
while (now.getMonth() == originalMonth) { // its an enum, you can do this
    now = now.plusWeeks(-1);
    i++;
}

System.out.println(i); // prints 1

答案 3 :(得分:0)

String[] arr = { "2018-01-01", "2018-01-07", "2018-01-30", "2018-01-22", 
               "2018-01-25" };
for (String str : arr) {
    LocalDate ld = LocalDate.parse(str);
    ld = ld.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
    int res = (ld.getDayOfMonth()/7) + 
                   (Integer.min(1, ld.getDayOfMonth() % 7));
    System.out.printf("%s  => %d\n", str, res);
}