【问题标题】:java.time.format.DateTimeParseException when milliseconds in 2 digit onlyjava.time.format.DateTimeParseException 仅 2 位毫秒时
【发布时间】:2018-04-18 14:21:15
【问题描述】:

我正在使用 java8 格式化程序解析 '2018-04-12 15:12:32.999' 之类的日期。当我有一个 3 位数的毫秒数时它工作正常,例如这个日期'2018-04-12 15:12:32.999',但是当日期只有 2 位数毫秒时,它失败并抛出异常 java.time.format.DateTimeParseException: Text '2018-04-18 15:27:10.77' could not be parsed at index 20,你能建议如何解析这个日期。

我的格式化程序正在使用“yyyy-MM-dd HH:mm:ss.SSS" 模式。我的代码是这样的:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime.parse(dateStr,formatter);

【问题讨论】:

    标签: java java-time datetime-parsing date


    【解决方案1】:
    String dateStr = "2018-04-12 15:12:32.99";
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd HH:mm:ss")
                .appendFraction(ChronoField.MILLI_OF_SECOND, 2, 3, true)
                .toFormatter();
    System.out.println(LocalDateTime.parse(dateStr, formatter));
    

    其中 2,3 - 字段的最小、最大宽度

    输出:

    2018-04-12T15:12:32.990

    【讨论】:

    • 如果毫秒只是个位数怎么办?
    • 那么您需要将 min-width 从 2 设置为 1,它将正确执行: 2018-04-12T15:12:32.900 如下所示: .appendFraction(ChronoField.MILLI_OF_SECOND, 1, 3,真的)
    • 嘿,谢谢它现在正在工作。早些时候它没有得到一些错误,但现在它正在工作。为答案 +1
    【解决方案2】:

    有几个选项。我会选择这个:

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .toFormatter();
        String dateTimeString = "2018-04-18 15:27:10.77";
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
        System.out.println(dateTime);
    

    输出:

    2018-04-18T15:27:10.770

    DateTimeFormatter.ISO_LOCAL_TIME 可选择接受小数点和一到九位数字。我更喜欢使用构建器来组合预定义的格式化程序,而不是从头开始构建我自己的。

    有些人更喜欢较短的。我个人觉得它有点hacky:

        dateTimeString = dateTimeString.replace(' ', 'T');
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeString);
    

    输出是一样的。我们正在利用两个事实:(1) 单参数 LocalDateTime.parse 解析 ISO 8601 格式。 (2) 您的输入字符串非常接近 ISO 8601 格式,只是缺少表示时间部分开始位置的T

    您不需要第三个选项,但为了完整起见,我想提一下:如果从头开始构建格式化程序并需要可变的小数位数,请使用 DateTimeFormatterBuilder(我在第一个中使用的类sn-p) 和its appendFraction method。它使您可以控制小数的最小和最大数量。

    【讨论】:

      【解决方案3】:

      15:12:32:999 包含一个冒号 :。您的模式 HH:mm:ss.SSS 包含一个点 . 这将不匹配。

      这行得通。

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      
      public class Playground {
      
          public static void main(String[] args) throws ParseException {
              String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
      
              String s1 = "2018-04-12 15:12:32.999";
              String s2 = "2018-04-18 15:27:10.77";
      
              SimpleDateFormat sdf = new SimpleDateFormat(pattern);
      
              Date d1 = sdf.parse(s1);
              System.out.println(d1);
      
              Date d2 = sdf.parse(s2);
              System.out.println(d2);
          }
      
      }
      

      输出:

      Thu Apr 12 15:12:32 CEST 2018
      Wed Apr 18 15:27:10 CEST 2018
      

      【讨论】:

      • 抱歉,输入错误,第一个日期也包含 .不是:而且我使用的是 Java8 DateTimeFormatter 而不是 SimpleDateFormat .. 代码是这样的.. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); LocalDateTime.parse(dateStr,formatter);
      • 请编辑您的问题。不要将代码放入评论中。
      • 当 OP 说“使用 java8 格式化程序”时,使用早已过时且臭名昭著的麻烦 SimpleDateFormat 的答案是不合适的(我已经为 OP 编辑​​了问题)。顺便说一句,我也认为这个答案给出了不正确的结果。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多