【问题标题】:How to parse datetime with optional sections?如何使用可选部分解析日期时间?
【发布时间】:2017-07-07 17:11:34
【问题描述】:

我的日期时间可能是以下格式之一:

  • 月/日/年
  • 月/日/年
  • 月/日/年
  • 月/日/年
  • 以上任何一项,带 HH:mm
  • 以上任何一项,年份为 4 位数

我搭建的DateTimeFormatter如下:

new DateTimeFormatterBuilder()
    .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
    .appendLiteral('/')
    .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
    .appendLiteral('/')
    .appendValue(ChronoField.YEAR_OF_ERA, 2, 4, SignStyle.NEVER)
    .optionalStart()
    .appendLiteral(' ')
    .appendValue(HOUR_OF_DAY, 2)
    .appendLiteral(':')
    .appendValue(MINUTE_OF_HOUR, 2)
    .toFormatter();

但它无法格式化2/9/17。为什么?

【问题讨论】:

  • 解析两位数年份与解析具有不同宽度 (2-4) 的正常年份完全不同,比较 appendValueReduced(...) 与您使用 appendValue(YEAR_OF_ERA, 2, 4, ...) 的方法。
  • @MenoHochschild 使用 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 4, 2017) 给出错误“无法解析文本 '2/9/17':无法从 TemporalAccessor 获取 LocalDateTime:{},ISO 解析为 2017-02-09键入 java.time.format.Parsed"

标签: java date datetime java-8 datetime-format


【解决方案1】:

这行得通:

new DateTimeFormatterBuilder()
    .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
    .appendLiteral('/')
    .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
    .appendLiteral('/')
    .appendValueReduced(ChronoField.YEAR, 2, 4, yearMonth.getYear())
    .appendPattern("[ HH:mm]")
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .toFormatter();

我为响应 Meno Hochschild 的评论而发布的错误已通过设置可选小时和分钟的默认值得到修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    相关资源
    最近更新 更多