【问题标题】:JSR-310 - parsing seconds fraction with variable lengthJSR-310 - 解析可变长度的秒分数
【发布时间】:2015-07-18 03:36:00
【问题描述】:

有没有一种方法可以创建 JSR-310 格式化程序,它能够解析以下日期/时间以及可变长度的秒分数?

2015-05-07 13:20:22.276052

2015-05-07 13:20:22.276

示例代码:

DateTimeFormatter formatter
= new java.time.format.DateTimeFormatterBuilder()
        .append( java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") )
        .appendOptional( java.time.format.DateTimeFormatter.ofPattern(".SSSSSS") )
        .toFormatter();
formatter.parse("2015-05-07 13:20:22.276052", LocalDateTime::from);

【问题讨论】:

    标签: java java-time


    【解决方案1】:

    解析失败,日期时间没有任何“:”字符:

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyyMMddHHmmss")
                .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 9, false)
                .toFormatter();
            System.out.println(LocalDateTime.parse("20150507132022123", formatter));
    

    编辑:它是 appendFraction(),它需要 "." 字符。

    【讨论】:

      【解决方案2】:

      这样就解决了问题:

      DateTimeFormatter formatter = new DateTimeFormatterBuilder()
          .appendPattern("yyyy-MM-dd HH:mm:ss")
          .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
          .toFormatter();
      
      System.out.println(LocalDateTime.parse("2015-05-07 13:20:22.276052", formatter));
      System.out.println(LocalDateTime.parse("2015-05-07 13:20:22.276", formatter));
      System.out.println(LocalDateTime.parse("2015-05-07 13:20:22", formatter));
      
      // output
      2015-05-07T13:20:22.276052
      2015-05-07T13:20:22.276
      2015-05-07T13:20:22
      

      answer by JiriS 不正确,因为它使用appendValue,而正确的方法是使用DateTimeFormatterBuilder.appendFraction(它也处理小数点)。在第二个系统中可以看到差异,其中appendValue 错误地解析了“2015-05-07T13:20:22.000276”。

      在解析时,LocalDateTime.parse(str, formatter) 在大多数情况下比直接使用格式化程序更简洁。

      使用builder 时,利用appendPattern()optionalStart() 保持整洁。

      【讨论】:

      • 这里建议使用LocalDateTime.parse而不是直接使用格式化程序。然而DateTimeFormatter.parse 的文档却恰恰相反:“大多数应用程序应该使用这种方法进行解析。” …LocalDateTime dt = parser.parse(str, LocalDateTime::from);
      • 我看到了混乱。短语“大多数应用程序应使用此方法进行解析”与DateTimeFormatter 中的其他解析方法相同。它并不是为了与LocalDate 等类上的parse() 方法进行比较。因此我的回答是正确的,用户应该更喜欢LocalDate.parse 而不是DateTimeFormatter.parse
      • 有没有办法用 only 一个模式字符串来创建这样的格式化程序?
      • 没有。模式是可能的格式化程序的一个子集。
      • 仅供参考,在它编写后的几年里,appendFraction 签名似乎并没有出现在最新的几个版本中(至少在 Maven Central,2.9.9+ 上)。我找不到任何适用于微秒的替代方案。
      【解决方案3】:

      这一个有效

      DateTimeFormatter formatter
      = new java.time.format.DateTimeFormatterBuilder()
              .append( java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") )
              .appendOptional(
                      new java.time.format.DateTimeFormatterBuilder()
                          .appendLiteral('.')
                          .appendValue( ChronoField.MICRO_OF_SECOND, 1, 6, SignStyle.NOT_NEGATIVE).toFormatter())
              .toFormatter();
      

      【讨论】:

      • 此答案对appendValue 的使用并非在所有情况下都有效。详情请参阅Answer by JodaStephen
      猜你喜欢
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 2013-04-07
      相关资源
      最近更新 更多