DateTimeFormatter 可以解析,但不能为相同的输入格式化
DateTimeFormatter can parse, but not format for same input
模式 "yyyy_'w'w"
的 DateTimeFormatter
无法格式化已解析的值。
val df = DateTimeFormatter.ofPattern("yyyy_'w'w")
df: DateTimeFormatter = Value(YearOfEra,4,19,EXCEEDS_PAD)'_''w'Localized(WeekOfWeekBasedYear,1)
val week = df.parse("2017_w19")
week: temporal.TemporalAccessor = {Year=2017, WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=19},ISO
df.format(week)
错误是:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
java.time.format.Parsed.getLong(Parsed.java:203)
java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
这是为什么?
对我来说,您不能使用 DateTimeFormatter 来格式化 TemporalAccessor,它对于时间来说是一个过于宽泛的接口。首先尝试将其转换为 DateTime 对象。
模式 yyyy
代表 year-of-era field. But according to javadoc, there's also the pattern uuuu
to represent the year field(阅读这些链接以了解它们之间的细微差别 - 尽管对于当前日期而言差别不大)。
问题是:当您使用 y
创建格式化程序时,它使用 时代 字段,正如您可以通过值看到的那样:
Value(YearOfEra,4,19,EXCEEDS_PAD)
但是在解析时,生成的解析对象(在您的例子中是 week
变量)是使用 year 字段创建的 - 正如您可以通过值看到的:
{Year=2017, ...
格式化程序使用 年代 字段设置。因此,当您尝试格式化 week
时,它会尝试从 week
变量中获取此字段。由于此字段不存在(week
仅包含 year,但不包含 year-of-era),它抛出 UnsupportedTemporalTypeException
.
解决方案是在格式化程序中使用 year 字段(u
模式):
val df = DateTimeFormatter.ofPattern("uuuu_'w'w")
println(df)
val week = df.parse("2017_w19")
println(week)
println(df.format(week))
输出将是:
Value(Year,4,19,EXCEEDS_PAD)'_''w'Localized(WeekOfWeekBasedYear,1)
{Year=2017, WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=19},ISO
2017_w19
请注意,现在格式化程序是使用 year 字段创建的,并且 format
方法现在尝试从解析的对象中获取此字段,并且没有例外抛出。
模式 "yyyy_'w'w"
的 DateTimeFormatter
无法格式化已解析的值。
val df = DateTimeFormatter.ofPattern("yyyy_'w'w")
df: DateTimeFormatter = Value(YearOfEra,4,19,EXCEEDS_PAD)'_''w'Localized(WeekOfWeekBasedYear,1)
val week = df.parse("2017_w19")
week: temporal.TemporalAccessor = {Year=2017, WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=19},ISO
df.format(week)
错误是:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra
java.time.format.Parsed.getLong(Parsed.java:203)
java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
这是为什么?
对我来说,您不能使用 DateTimeFormatter 来格式化 TemporalAccessor,它对于时间来说是一个过于宽泛的接口。首先尝试将其转换为 DateTime 对象。
模式 yyyy
代表 year-of-era field. But according to javadoc, there's also the pattern uuuu
to represent the year field(阅读这些链接以了解它们之间的细微差别 - 尽管对于当前日期而言差别不大)。
问题是:当您使用 y
创建格式化程序时,它使用 时代 字段,正如您可以通过值看到的那样:
Value(YearOfEra,4,19,EXCEEDS_PAD)
但是在解析时,生成的解析对象(在您的例子中是 week
变量)是使用 year 字段创建的 - 正如您可以通过值看到的:
{Year=2017, ...
格式化程序使用 年代 字段设置。因此,当您尝试格式化 week
时,它会尝试从 week
变量中获取此字段。由于此字段不存在(week
仅包含 year,但不包含 year-of-era),它抛出 UnsupportedTemporalTypeException
.
解决方案是在格式化程序中使用 year 字段(u
模式):
val df = DateTimeFormatter.ofPattern("uuuu_'w'w")
println(df)
val week = df.parse("2017_w19")
println(week)
println(df.format(week))
输出将是:
Value(Year,4,19,EXCEEDS_PAD)'_''w'Localized(WeekOfWeekBasedYear,1)
{Year=2017, WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=19},ISO
2017_w19
请注意,现在格式化程序是使用 year 字段创建的,并且 format
方法现在尝试从解析的对象中获取此字段,并且没有例外抛出。