【问题标题】:How to force java.time.LocalDate to assume 19th century as YY year pattern? [duplicate]如何强制 java.time.LocalDate 假设 19 世纪为 YY 年模式? [复制]
【发布时间】:2016-07-13 14:13:22
【问题描述】:

以下测试失败:'86 生日格式为 2068。如何格式化为1986

    @Test
    public void testBirthday() {
        assertEquals("1986-08-07", java.time.LocalDate.parse("070886", 
             java.time.format.DateTimeFormatter.ofPattern("ddMMyy")));
    }

失败:

java.lang.AssertionError: expected:<1986-08-07> but was:<2086-08-07>

这与 org.joda.time 库有很大不同,后者会在此处正确假定为 19'

/旁注:关于“重复”问题中的标记答案,我认为这不是重复的!

【问题讨论】:

  • 滑稽的答案是使用org.joda.time
  • 不,不是。 joda 实际上已“弃用”并且不再开发。至少作者自己现在建议切换到 java8 java.time
  • 请注意,这是记录在案的行为:“如果字母数为两个,则使用减少的两位数形式。对于打印,这会输出最右边的两位数。对于解析,这将使用 2000 的基值进行解析,从而得出 2000 到 2099 范围内的年份。”不幸的是,它没有说明如何改变这种行为。您也许可以指定一个单独的 ResolverField,但感觉有点做作。您可能会发现手动“修复”字符串以使用四位数年份更简单。
  • 编写自己的解析方法。 java.time.LocalDate.parse 应该如何知道您的期望? “070886”不包含有关世纪的信息。
  • 由于您使用的是解析函数,您可以提供模式ddMMyyyy 和时间07081986

标签: java java-time


【解决方案1】:

可以使用DateTimeFormatterBuilder.appendValueReduced()控制基准年。

此代码将使用 1900 年而非 2000 年的基准日期进行解析:

DateTimeFormatter f = new DateTimeFormatterBuilder()
  .appendPattern("ddMM")
  .appendValueReduced(ChronoField.YEAR, 2, 2, 1900)
  .toFormatter();
LocalDate date = LocalDate.parse("070886", f);

【讨论】:

  • 上面的代码完全坏掉了。它甚至不使用格式化程序!
【解决方案2】:

Java 8 的 LocalDate 类默认使用 2000+ 作为年份。为了解析 1900 及以上的 yy 格式,您需要自己减少时间。

当然,即使您对照当前年份检查日期并在今天之后减去 100 年,此修复程序也不适用于 100 岁以上的人。

您也可以使用yyyy 格式。或者直接使用 Date 对象,如果您愿意,可以将其转换为 LocalDate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多