Java LocalDate如何将一年的最后一周设置为第53周而不是新年的第一周? 如果你认为这一周将从开始,每年01周开始,代码 ,然后在2019周将有53周。 上述2019年1月29日、30日、31日将进入2019年第53周

Java LocalDate如何将一年的最后一周设置为第53周而不是新年的第一周? 如果你认为这一周将从开始,每年01周开始,代码 ,然后在2019周将有53周。 上述2019年1月29日、30日、31日将进入2019年第53周,java,java-time,week-number,Java,Java Time,Week Number,如基于年份的周的文档中所示,所有三个字段都根据其有效值范围进行验证。基于周的年份字段的有效期从1到52或53不等,具体取决于基于周的年份。 因此,我假设以下代码应该给出如下输出:基于周的年的周53&基于周的年2019 但它的输出是:1和2020 import java.time.LocalDate; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.

如基于年份的
周的文档中所示,
所有三个字段都根据其有效值范围进行验证。基于周的年份字段的有效期从1到52或53不等,具体取决于基于周的年份。

因此,我假设以下代码应该给出如下输出:
基于周的年的周
53&
基于周的年
2019

但它的输出是:12020

import java.time.LocalDate;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.IsoFields;

public class WeekStartDemo {
    public static void main(String args[]) {
        DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
                .ofPattern("uuuu-MM-dd")
                .withChronology(IsoChronology.INSTANCE)
                .withResolverStyle(ResolverStyle.STRICT);

        LocalDate updatedDate = LocalDate.parse("2019-12-30", DATE_FORMATTER);

        System.out.println(updatedDate.toString());

        System.out.println(updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR));
        System.out.println(updatedDate.get(IsoFields.WEEK_BASED_YEAR));
    }
}
如果我将日期传递为
2019-12-28
,那么它将返回
WEEK\u-OF-WEEK\u-BASED\u-YEAR
52
WEEK\u-BASED\u-YEAR
2019。但在2019年最后一周(即第53周)不起作用


让我知道我在上面的代码中遗漏了什么。

这里的问题是给定的一年有365天或366天(后者是闰年),这意味着每年有1天或2天超出52周。国际标准化组织(ISO)的周年制度就是解决这个问题的方法,这意味着有时一年的第一周可能不会从1月1日开始,一年的最后一天也不会在第52周。这里的一个解决方法是只计算从每年年初开始的一周,例如

LocalDate firstOfYear = LocalDate.of(2019, Month.JANUARY, 1);
LocalDate updatedDate = LocalDate.of(2019, Month.DECEMBER, 30);

int diff = (int)ChronoUnit.DAYS.between(firstOfYear, updatedDate);
int week = 1 + (diff / 7);
System.out.println("The week number is: " + week);
根据ISO-8601(),这是正确的。2019年第53周没有日历。根据定义,一年中的第01周是今年第一个星期四,相当于包含1月4日的一周。
据我所知,这样做是为了避免cw 1没有工作日。

正如我在评论中提到的,从您的Javadoc链接中,基于周的年份本身是相对于标准ISO预期年份定义的。它与标准年的不同之处在于,它总是在周一开始(而不是周日)。使用发布的代码很容易找到53周的年份,从
1900
迭代到
2300
,解析给定年份最后一天的
WEEK\u OF_WEEK\u BASED\u YEAR
,并在53处打印值。像

DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd")
        .withChronology(IsoChronology.INSTANCE)
        .withResolverStyle(ResolverStyle.STRICT);

for (int i = 1900; i < 2300; i++) {
    LocalDate updatedDate = LocalDate.parse(String.format("%d-12-31", i), DATE_FORMATTER);
    if (updatedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) == 53) {
        System.out.println(i);
    }
}
向前跳一点

2009
2015
2020
2026
因此,今年(2020年)有53周,2019年没有

    LocalDate date = LocalDate.of(2019, Month.DECEMBER, 30);
    int weekOfYear = date.get(WeekFields.SUNDAY_START.weekOfYear());
    System.out.println(weekOfYear);
此代码段的输出为:

五十三

我相信这就是
WeekFields.weekOfWeekBasedYear()
WeekFields.weekOfYear()
之间的确切区别

正如艾略特·弗里希(Elliott Frisch)所提到的,您的主要困惑源可能是使用了错误的week字段。您使用的ISO周字段将星期一定义为一周的第一天,将一年中的第一周定义为一年中至少包含4天的第一周。相反,你说你想要:

如果你认为这一周将从每年的<代码> 01版< /代码>开始。 每周开始时间为

周日

根据您的评论:

…新的一周(
week-01
)是否总是从每年的
1月1日开始

是的,会的

如何在今年的
周执行负1周?至于
Jan
012020
一周
将是2020年第01周
。什么类型的
负1
周
我可以执行以获得2019年第53周
?我试过了 带有
date.minus weeks(1)
但返回
Week-52 2019


我们需要专门处理第一周的案子。减去1周,我们知道我们进入了去年的12月。选择该月的最后一天将显示12月31日。这总是在一年的最后一周(通常是第53周;如果闰年从星期六开始,我认为2000年和2028年就是这样的例子,偶尔是第54周)。

基于周的年份本身是相对于标准ISO预期年定义的。它与标准年的不同之处在于它总是在星期一开始。这种手持转换是否必要?问这个问题,因为如果是这样的话,我会感到惊讶。@Ole我也会感到惊讶,但我对Java 8 date API不太了解。我认为我的答案至少是正确的,即OP希望计算年周数,或者将周定义为从1月1日开始。我知道这个解决方案是直截了当的。但我更关注的是Java的内部API,它将在本周提供。因为你不能在其中设置周开始/周最小天数等。这是正确的,我错过了文档
基于周的一年的第一周是标准*ISO年的第一个基于周一的一周,在新的一年中至少有4天。
但是我可以使用哪些Java API来满足我的要求,这一周总是从1月1日开始&它将在即将到来的第一个
周六结束
如果新的一周开始是“代码>星期日< /代码>)如果你使用“代码> ISO前瞻性年< /代码>,那么2019个星期是正确的。是的,我很抱歉,我错过了JavaDoc的<代码> iFields<代码>。但是如果你考虑<代码>周开始:星期日< /代码>和从每个代码> JAN 01 <代码>新星期(即周-01)。在这种情况下2019年开始将有53周。上周53将有“3天:29,30,31。这是我在我的专栏文章中发布的。我同意你和@Elliott Frisch的观点,我对比了两件事。但如果我使用你在这种情况下提供的内容,新的一周(
Week-01
)将始终在每年的
1月1日
开始?但每周有1/2/3/4天。与今年(2020年)一样,
1周
将从
2020年1月1日
2020年1月4日
02周
将从
2020年1月5日
2020年1月1日
    LocalDate date = LocalDate.of(2019, Month.DECEMBER, 30);
    int weekOfYear = date.get(WeekFields.SUNDAY_START.weekOfYear());
    System.out.println(weekOfYear);
    LocalDate dateInWeek1 = LocalDate.of(2020, Month.JANUARY, 3);
    int weekOfYear = dateInWeek1.get(wf.weekOfYear());
    System.out.println(weekOfYear);
    LocalDate dateInPreviousWeek;
    if (weekOfYear == 1) {
        dateInPreviousWeek = dateInWeek1.minusWeeks(1)
                .with(TemporalAdjusters.lastDayOfMonth());
    }
    else {
        dateInPreviousWeek = dateInWeek1.minusWeeks(1);
    }
    System.out.format("%s %2d%n", dateInPreviousWeek, dateInPreviousWeek.get(wf.weekOfYear()));