【问题标题】:java.time.format.DateTimeParseException: Text could not be parsed at index 3java.time.format.DateTimeParseException:无法在索引 3 处解析文本
【发布时间】:2017-12-09 02:23:12
【问题描述】:

我正在使用 Java 8 来解析日期并找出两个日期之间的差异。

这是我的 sn-p:

String date1 ="01-JAN-2017";
String date2 = "02-FEB-2017";

DateTimeFormatter df = DateTimeFormatter .ofPattern("DD-MMM-YYYY", en);
LocalDate  d1 = LocalDate.parse(date1, df);
LocalDate  d2 = LocalDate.parse(date2, df);

Long datediff = ChronoUnit.DAYS.between(d1,d2);

当我运行时出现错误:

java.time.format.DateTimeParseException:无法在索引 3 处解析文本

【问题讨论】:

标签: java-8 java-time date-parsing


【解决方案1】:

首先,check the javadoc。大写的D代表day-of-year字段(不是你想要的day-of-month),大写的Y代表 week-based-year 字段(不是您想要的 year)。正确的模式是小写字母dy

另外,您使用大写字母的月份名称(JANFEB),因此您的格式化程序必须不区分大小写(默认行为是只接受 @987654328 之类的值@ 和 Feb)。而且这些月份名称是英文缩写,因此您还必须使用英文语言环境以确保正确解析名称(使用java.util.Locale 类)。

所以,你的格式化程序应该是这样创建的:

DateTimeFormatter df = new DateTimeFormatterBuilder()
    // case insensitive to parse JAN and FEB
    .parseCaseInsensitive()
    // add pattern
    .appendPattern("dd-MMM-yyyy")
    // create formatter (use English Locale to parse month names)
    .toFormatter(Locale.ENGLISH);

这将使您的代码正常工作(datediff 将变为 32)。

【讨论】:

  • 非常好的答案。涵盖所有相关的内容,并且切中要害。
  • 添加区域设置很关键,并且从我的错误消息中并不明显(DateTimeParseException:无法在索引 0 处解析文本)。感谢您的提示!
【解决方案2】:

以下代码有效。问题是您使用的是“JAN”而不是“Jan”。 DateTimeFormatter 似乎无法识别。并将模式更改为 “d-MMM-yyyy”。

  String date1 ="01-Jan-2017";
  String date2 = "02-Feb-2017";

  DateTimeFormatter df = DateTimeFormatter.ofPattern("d-MMM-yyyy");
  LocalDate  d1 = LocalDate.parse(date1, df);
  LocalDate  d2 = LocalDate.parse(date2, df);

  Long datediff = ChronoUnit.DAYS.between(d1,d2);  

来源:https://www.mkyong.com/java8/java-8-how-to-convert-string-to-localdate/

【讨论】:

  • 谢谢。有用。我还有一个问题。它还会照顾 DayLightSaving 时间吗?
  • 你不会对夏令时有任何问题,@Uma。即使 DST 从 3 月 26 日开始,从 3 月 25 日到 3 月 26 日还有 1 天。使用LocalDate 时,完全忽略了实际上只有 23 小时。事实上,LocalDate 完全忽略了任何时区,因此完全忽略了任何 DST。
【解决方案3】:
// DateTimeFormatterBuilder provides custom way to create a
    // formatter
    // It is Case Insensitive, Nov , nov and NOV will be treated same
    DateTimeFormatter f = new DateTimeFormatterBuilder().parseCaseInsensitive()
            .append(DateTimeFormatter.ofPattern("yyyy-MMM-dd")).toFormatter();
    try {
        LocalDate datetime = LocalDate.parse("2019-DeC-22", f);
        System.out.println(datetime); // 2019-12-22
    } catch (DateTimeParseException e) {
        // Exception handling message/mechanism/logging as per company standard
    }

【讨论】:

    【解决方案4】:

    尝试使用DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-LLL-yyyy",Locale.ENGLISH);

    【讨论】:

    • 我确实尝试过,但它对我没有用。它只能通过使用其他解决方案中提到的 parseCaseInsensitive() 来工作。
    【解决方案5】:

    也许你可以使用这个通配符,

     String d2arr[] = {
                "2016-12-21",
                "1/17/2016",
                "1/3/2016",
                "11/23/2016",
                "OCT 20 2016",
                "Oct 22 2016",
                "Oct 23", // default year is 2016
                "OCT 24",  // default year is 2016
        };
    
        DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
                .parseCaseInsensitive().parseLenient()
                .parseDefaulting(ChronoField.YEAR_OF_ERA, 2016L)
                .appendPattern("[yyyy-MM-dd]")
                .appendPattern("[M/dd/yyyy]")
                .appendPattern("[M/d/yyyy]")
                .appendPattern("[MM/dd/yyyy]")
                .appendPattern("[MMM dd yyyy]");
    
        DateTimeFormatter formatter2 = builder.toFormatter(Locale.ENGLISH);
    

    https://coderanch.com/t/677142/java/DateTimeParseException-Text-parsed-unparsed-textenter link description here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2018-04-04
      • 2018-12-12
      相关资源
      最近更新 更多