java.time.DateTimeFormat意外行为

时间:2016-02-01 07:14:47

标签: java java-time

在Java 8 java.time包中,LocalDate使用DateTimeFormatter.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");

整整一周后!为什么?什么咒语会使我的自定义模式与内置模式相同?

2 个答案:

答案 0 :(得分:2)

Java 8使用Builder

以下是DateTimeFormatter.ISO_WEEK_DATE的实施。源使用BuilderDateTimeFormatterBuilder)而不是编码的字符串。

来自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 |定制:2015-W53-1

     

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

答案 1 :(得分:1)

在这里回答类似的问题:Inconsistent `w` symbol formatting from joda time to java.time

似乎问题就像Basil提到的Locale一样。