我希望这两个格式化程序是等效的:
DateTimeFormatter fromBuilder = new DateTimeFormatterBuilder()
.appendValue(IsoFields.WEEK_BASED_YEAR, 4)
.appendLiteral('-')
.appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
.toFormatter();
DateTimeFormatter fromPattern = DateTimeFormatter.ofPattern("YYYY-ww");
但结果并不相同:
LocalDate date = LocalDate.of(2017, 1, 1);
System.out.printf("from builder: %s%n", fromBuilder.format(date)); // prints 'from builder: 2016-52'
System.out.printf("from pattern: %s%n", fromPattern.format(date)); // prints 'from pattern: 2017-01'
我错过了什么?
1条答案
按热度按时间sdnqo3pr1#
这个
Y
以及w
模式对应于周字段的本地化版本,使用jvm的默认区域设置(java.util.Locale
). 第二个格式化程序等效于:由于这依赖于区域设置,因此它可以或不能像
IsoFields
. 这个WeekFields
根据jvm的默认语言环境,上面创建的代码将具有不同的行为。IsoFields
另一方面,遵循iso-8601定义来定义基于周的字段,如javadoc中所述:以周为单位的年份的第一周是标准iso年份的第一个以周一为单位的周,在新的一年中至少有4天。
如果1月1日是星期一,那么第一周从1月1日开始
如果1月1日是星期二,那么第1周从上一标准年的12月31日开始
如果1月1日是星期三,那么第1周从上一标准年的12月30日开始
如果1月1日是星期四,那么第1周从上一标准年的12月29日开始
如果1月1日是星期五,那么第一周从1月4日开始
如果1月1日是星期六,那么第一周从1月3日开始
如果1月1日是星期天,那么第一周从1月2日开始
作为
2017-01-01
是一个星期日,它对应于上面最后一行:第一周从2017年1月2日开始,所以2017年1月1日仍然是2016年的最后一周。你可以检查你的
WeekFields
示例不同于IsoFields
通过调用方法getFirstDayOfWeek()
以及getMinimalDaysInFirstWeek()
-用于计算基于相应周的字段的值:一周的定义如下:
一周的第一天。例如,iso-8601标准将星期一视为一周的第一天。
第一周的最小天数。例如,iso-8601标准将第一周计算为至少需要4天。
这两个值一起允许将一年或一个月划分为几周。
在我使用的jvm中,默认的语言环境是
pt_BR
,和WeekFields
created将一周的第一天设为星期日,将第一周的最少天数设为1
. 检查一下你的,你会发现它也不同于IsoFields
.您可以使用常量检查iso的定义
WeekFields.ISO
:getFirstDayOfWeek()
周一和周五返回getMinimalDaysInFirstWeek()
退货4
.另外,提醒一下
IsoFields
以及WeekFields.ISO
. 引用jodastephen的评论:唯一可以观察到的区别是weekfields在所有日历系统上运行(通过转换为iso),而isofields只在iso上运行(并拒绝其他日历系统)