在 java.time 中,为什么 WeekFields.SUNDAY_START 为 2020-12-29 生成的周数为 1,而不是 53?

Bty*_*jor 2 java datetime

我确信我在这里错过了一些东西,但它仍然让我困惑。

为什么 SUNDAY_START 生成的 2020 年 12 月 29 日周数为 1,而不是 53?

是因为我误解了 Oracle 文档的内容吗?或者我还错过了什么?

细节

转到https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/temporal/WeekFields.html#SUNDAY_START显示 SUNDAY_START 似乎遵循与上述相同的规则。如果我使用下面的代码...

ZonedDateTime zdt = ZonedDateTime.ofInstant(/* representation of Dec. 29, 2020 */, ZoneId.of("UTC"));
 
TemporalField wn = WeekFields.SUNDAY_START.weekOfWeekBasedYear();
    
int weekNumber = zdt.get(wn);
Run Code Online (Sandbox Code Playgroud)

那么“weekNumber”是 1,而我预计它是 53。

如果我使用WeekFields.ISO改为使用,我会得到 53;然而,ISO 的定义是它使用星期一作为一周的开始,这在我正在处理的情况下是不正确的,并且我不确定仅使用 ISO 而不是 SUNDAY_START 的未来后果。

我缺少什么?

答案

根据下面的评论(感谢 Basil 和 Andreas),我确实误读了 Oracle 文档,其中指出:

Defined as starting on Sunday and with a minimum of 1 day in the month.

“每月至少一天”是让我在新的一年中陷入困境的部分。

通过以下说明,可以清楚地看出,由于 2021 年 1 月 1 日是星期五,并且 SUNDAY_START 周从星期日开始,因此在这种情况下,本周实际上是第 1 周。

动机

我最初提出这个问题是为了更好地理解 SUNDAY_START。这样做的动机是找到一种方法来重新创建 MySQL 的 WEEK()“模式 6”(即,从周日开始一周,第 1 周是今年有 4 天或更多天的第一周)。

我忘记了创建具有指定开始日期和该月包含的最小天数的自定义周字段的功能。

尽管如此,我还是很高兴能够澄清我对 SUNDAY_START 的 Javadocs 的误解,并且我希望这篇文章对将来的人有用。

感谢大家的评论和回答,对于最初的困惑,我深表歉意。

And*_*eas 5

https://savvytime.com/week-number错误的

当您显示Country: United States,时Year: 2020,它显示:

Week 53   December 27, 2020   January 2, 2021   Current Week
Run Code Online (Sandbox Code Playgroud)

当您显示Country: United States,时Year: 2021,它显示:

Week 1    December 27, 2020   January 2, 2021   Current Week
Run Code Online (Sandbox Code Playgroud)

第 53 周和第 1 周怎么可能是同一日期范围?不可以。该网站已损坏。


更新:来自评论:

WEEK()需要使用模式 6的 MySQL 函数的 Java 日期时间“等效项”

这很容易。模式6定义为:

  • 一周的第一天:星期日
  • 第 1 周是今年第一周……有 4 天或更多天

所以你会得到一个WeekFields

WeekFields weekMode6 = WeekFields.of(/*firstDayOfWeek=*/DayOfWeek.SUNDAY,
                                     /*minimalDaysInFirstWeek=*/4);
Run Code Online (Sandbox Code Playgroud)

作为参考,两个预定义WeekFields实例定义为:

ISO         = new WeekFields(DayOfWeek.MONDAY, 4);
SUNDAY_START = WeekFields.of(DayOfWeek.SUNDAY, 1);
Run Code Online (Sandbox Code Playgroud)