tangguo

将字符串解析为本地日期未使用所需的世纪

java

我正在使用此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年吗?

谢谢你的帮助


阅读 281

收藏
2020-12-01

共1个答案

一尘不染

由于这个问题确实与新java.time包装有关,因此SimpleDateFormat我不会引用以下相关章节:

年:字母的数量确定最小字段宽度,在该最小字段宽度以下使用填充。如果字母数为2,则使用简化的两位数形式。对于打印,这将输出最右边的两位数字。对于解析,这将使用2000的基值进行解析,从而得出2000到2099(含)之间的一年。

我们看到Java-8默认使用2000-2099范围,而不是- SimpleDateFormat80年,直到+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或适当的字段IsoFields.WEEK_BASED_YEAR。关于您没有其他与周相关的字段的事实,我将假定为正常的日历年,而不是基于周的日历年。

2020-12-01