13

我正在使用这个 DateTimeFormatter:

DateTimeFormatter.ofPattern("ddMMYY")

我想解析字符串150790,我得到了这个错误:

Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=15, MonthOfYear=7, WeekBasedYear[WeekFields[MONDAY,4]]=2090},ISO of type java.time.format.Parsed

显然,我想得到以下内容TemporalAccessor

{DayOfMonth=15, MonthOfYear=7, WeekBasedYear=1990}

你知道为什么我得到的是 2090 年而不是 1990 年吗?

谢谢你的帮助

4

1 回答 1

21

由于这个问题实际上是关于 new java.time-package 而不是SimpleDateFormat我将引用以下相关部分

年份:字母数决定了使用填充的最小字段宽度。如果字母数为两个,则使用简化的两位数形式。对于打印,这将输出最右边的两位数。对于解析,这将使用 2000 的基值进行解析,从而得到 2000 到 2099 范围内的年份。

我们看到 Java-8默认使用 2000-2099的范围,而不是SimpleDateFormat相对于今天的 -80 年到 +20 年的范围。

如果要配置它,则必须使用appendValueReduced()。这是以不方便的方式设计的,但有可能,请参见此处:

String s = "150790";

// old code with base range 2000-2099
DateTimeFormatter dtf1 = 
  new DateTimeFormatterBuilder().appendPattern("ddMMyy").toFormatter();
System.out.println(dtf1.parse(s)); // 2090-07-15

// improved code with base range 1935-2034
DateTimeFormatter dtf2 = 
  new DateTimeFormatterBuilder().appendPattern("ddMM")
  .appendValueReduced(
    ChronoField.YEAR, 2, 2, Year.now().getValue() - 80
  ).toFormatter();
System.out.println(dtf2.parse(s)); // 1990-07-15

顺便说一句,如果你真的想要基于周的年份,那么你必须使用 Y 而不是 y 或适当的 field IsoFields.WEEK_BASED_YEAR。关于您没有任何其他与周相关的字段这一事实,我会假设正常日历年,而不是基于周的日历年。

于 2015-04-07T16:10:15.027 回答