java.time.DateTimeFormat 意外行为

标签 java java-time

在 Java 8 java.time 包中,使用 LocalDateDateTimeFormatter.ISO_WEEK_DATE :

LocalDate date = LocalDate.of(2015, 12, 28);
date.format(DateTimeFormatter.ISO_WEEK_DATE).equals("2015-W53-1");

正如预期的那样,但是

date.format(DateTimeFormatter.ofPattern("YYYY'-W'ww'-'e")).equals("2016-W01-2");

那是整整一周之后!为什么?什么咒语能让我的自定义模式与内置模式一样工作?

最佳答案

Java 8 使用生成器

这是 DateTimeFormatter.ISO_WEEK_DATE 的实现.来源使用 Builder ( DateTimeFormatterBuilder ) 而不是编码字符串。

来自 this OpenJDK source code for Java 8这似乎是 Java 8 Update 72 之后的当前开发版本(我不熟悉 OpenJDK 站点)。

public static final DateTimeFormatter ISO_WEEK_DATE;
    static {
        ISO_WEEK_DATE = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .appendValue(IsoFields.WEEK_BASED_YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
                .appendLiteral("-W")
                .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 2)
                .appendLiteral('-')
                .appendValue(DAY_OF_WEEK, 1)
                .optionalStart()
                .appendOffsetId()
                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
    }

一周的第一天

我不知道问题的确切性质,但我怀疑这是一周第一天的定义。 ISO 标准说星期一开始一周。上面代码中的 .appendValue(DAY_OF_WEEK, 1) 行似乎使这一事实成为事实,尽管我不知道为什么这是必要的,因为最后指定了 IsoChronology上面一行。

语言环境

无论如何,问题肯定包含在Locale中。 .以下示例显示德国语言环境生成 2015-W53-1 而美国语言环境生成:2016-W01-2

LocalDate localDate = LocalDate.of ( 2015 , 12 , 28 );
String builtIn = localDate.format ( DateTimeFormatter.ISO_WEEK_DATE ); // 2015-W53-1

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "YYYY'-W'ww'-'e" );

formatter = formatter.withLocale ( Locale.GERMANY );  // 2015-W53-1
String custom = localDate.format ( formatter );
System.out.println ( "formatter.locale: " + formatter.getLocale () + " | localDate: " + localDate + " | builtIn: " + builtIn + " | custom: " + custom );

formatter = formatter.withLocale ( Locale.US );  // 2016-W01-2
custom = localDate.format ( formatter );
System.out.println ( "formatter.locale: " + formatter.getLocale () + " | localDate: " + localDate + " | builtIn: " + builtIn + " | custom: " + custom );

formatter.locale: de_DE | localDate: 2015-12-28 | builtIn: 2015-W53-1 | custom: 2015-W53-1

formatter.locale: en_US | localDate: 2015-12-28 | builtIn: 2015-W53-1 | custom: 2016-W01-2

关于java.time.DateTimeFormat 意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35124862/

相关文章:

java - 将整数传递给 Servlet

java - Java 8 DateTimeFormatters 常量在哪里定义?

JAVA EclipseLink 可选查询参数

java - 使用 Jenkins 进行集成测试

java - 如何将给定时间(字符串)转换为本地时间?

Java 8 偏移日期解析

java - 为什么 Java 的 DateTimeFormatter 不能安全地解析/格式化 Instant 上的往返?

java - 为什么 DateTimeFormatter 没有格式化我的字符串?

java - 做while循环错误(switch语句)

java - 如何将 jwplayer 与 rest 查询一起使用?