在 基于为期一周的年
场,根据的Javadoc,取决于两两件事:什么是一周的第一天,天在第一周的最低数量。
ISO标准将星期一定义为一周中的第一天,并且在第一周中至少要有4天:
System.out.println(WeekFields.ISO.getFirstDayOfWeek()); // MondaySystem.out.println(WeekFields.ISO.getMinimalDaysInFirstWeek()); // 4
(WeekFields.ISO.weekbasedYear()
相当于IsoFields.WEEK_baseD_YEAR
,与其他日历系统略有不同)
考虑到,例如,1月2日第二 2009年,这是一个星期五。检查javadoc中 基于周的年份
字段:
第一周(1)是从getFirstDayOfWeek()开始的一周,一年中至少有getMinimalDaysInFirstWeek()天。因此,第一周可能会在今年年初之前开始。
考虑到ISO定义(周从星期一开始,第一周的最少天数是4),第1周从2008 年12月29 日开始,到2009年1月4
日结束(这是从星期一开始的第一周,并且至少有4周2009年天),因此1月2日第二 2009年以来一个 基于为期一周的年
相当于2009年(与ISO的定义):
// January 2st 2009LocalDate dt = LocalDate.of(2009, 1, 2);System.out.println(dt.get(WeekFields.ISO.weekbasedYear())); // 2009System.out.println(dt.get(WeekFields.ISO.weekOfWeekbasedYear())); // 1// WeekFields.ISO and IsoFields are equivalentSystem.out.println(dt.get(IsoFields.WEEK_baseD_YEAR)); // 2009System.out.println(dt.get(IsoFields.WEEK_OF_WEEK_baseD_YEAR)); // 1
但是,如果我考虑一个语言环境的
WeekFields实例
en_MT(英语(马耳他)),则一周的第一天为星期日,而第一周的最少天数为4:
WeekFields wf = WeekFields.of(new Locale("en", "MT"));System.out.println(wf.getFirstDayOfWeek()); // SundaySystem.out.println(wf.getMinimalDaysInFirstWeek()); // 4System.out.println(dt.get(wf.weekbasedYear())); // 2008System.out.println(dt.get(wf.weekOfWeekbasedYear())); // 53从周日开始并且在2009年至少有4天的第一周是1月4 日至10 日。因此,根据周定义
en_MT的语言环境,1月2日第二 2009年属于 53
个星期的的 基于为期一周的年 2008年。
现在,如果我使用
ar_SA语言环境(阿拉伯语(沙特阿拉伯)),则该周从星期六开始,第一周的最少天数为1:
WeekFields wf = WeekFields.of(new Locale("ar", "SA"));System.out.println(wf.getFirstDayOfWeek()); // SaturdaySystem.out.println(wf.getMinimalDaysInFirstWeek()); // 1System.out.println(dt.get(wf.weekbasedYear())); // 2009System.out.println(dt.get(wf.weekOfWeekbasedYear())); // 1对于这个区域,本周1点开始在12月27日日 2008年结束在1月2日第二日(它的第一个星期是在一个周六开始,并具有至少1天,2009年)。因此,
基于周年 的1月2日第二,2009年
ar_SA区域也是2009年(我已经使用了相同的值
IsoFields,
即使一周的定义是完全不同于ISO )。
当
IsoFields.WEEK_baseD_YEAR使用ISO的定义时,该模式
YYYY将使用与
WeekFields格式化程序中设置的语言环境相对应的实例(如果未设置,则为JVM默认语言环境)。
根据每个语言环境的定义(一周的第一天和第一周的最少天数),本地化模式()中 基于周的年份
YYYY可能与ISO字段的值相同(或不相同)。
尽管一个星期可以在另一年开始或结束听起来很奇怪,但是javadoc说它是完全有效的:
一年的第一周和最后一周可能分别包含前一个日历年或下一个日历年的天。
模式字母
java.time基于CLDR(Unipre通用语言环境数据存储库)。关于基于周的模式的此链接说:
Y表示的年份通常从 语言环境 的一周的第一天开始,到一周的最后一天结束
无论如何,CLDR都是关于本地化的,
Y本地化也是如此-正如斯蒂芬·科尔本(StephenColebourne)在下面[的评论中所述:
CLDR的全部目的是本地化,因此,是的,“
Y”模式字母已本地化。尽管我了解对希望始终使用ISO规则运行的模式字母的渴望,但它并不存在,要添加CLDR很难甚至不可能。(Java紧紧追随CLDR)
我的结论是,如果要使用ISO周字段,请不要使用本地化模式。或者,作为一种(不太理想,非常丑陋的)解决方法,请使用与ISO星期定义匹配的语言环境(在我的JVM中,请按提示进行
Locale.FRENCH操作,作为
WeekFields.ISO.equals(WeekFields.of(Locale.FRENCH))return
true)。唯一的问题是,语言环境还会影响其他字段(如果您有月或星期几的名称,例如
MMM或
EEE,以及任何其他语言环境敏感数据)。



