【问题标题】:DateTimeFormatter unable to parse a Date String but SimpleDateFormat is able toDateTimeFormatter 无法解析日期字符串,但 SimpleDateFormat 能够
【发布时间】:2020-04-24 10:38:40
【问题描述】:

我无法使用 LocalDate 解析方法解析此示例日期字符串 - “312015”代表“2015 年 1 月 3 日”。 有人可以帮忙吗?

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class TestDOB {

    public static void main(String[] args) throws ParseException {
        // TODO Auto-generated method stub

        String dateOfBirth = "312015";
        SimpleDateFormat sdf = new SimpleDateFormat("dMyyyy");
        System.out.println(sdf.parse(dateOfBirth)); 
        // The above outputs Sat Jan 03 00:00:00 CST 2015

        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dMyyyy").withLocale(Locale.getDefault());
        LocalDate dateTime = LocalDate.parse(dateOfBirth, dateFormatter);

        // The above parsing statement with LocalDate parse method runs into below error - 


    }

}

Error on console- 

Exception in thread "main" java.time.format.DateTimeParseException: Text '312015' could not be parsed at index 6
    at java.time.format.DateTimeFormatter.parseResolved0(Unknown Source)
    at java.time.format.DateTimeFormatter.parse(Unknown Source)
    at java.time.LocalDate.parse(Unknown Source)
    at TestDOB.main(TestDOB.java:30)

【问题讨论】:

  • 你怎么能期望“31”被(可靠地)检测为“3rd Jan”,而不是“31st”? d 将匹配多个数字,因为有时它必须这样做。
  • 即使你强制dM 只匹配一个数字,那么1122019 呢?是1/12/2019 还是11/2/2019?不要使用允许以相同方式表示两个单独日期的格式。
  • 我有一个特殊要求来解析没有特殊字符或空格并且严格只包含数字的日期字符串
  • 为什么强制单 d 和单 M 在这里不起作用?我在这里错过了什么吗?
  • 即使它们只能是数字,为什么不使用两位数来表示日和月呢?

标签: java datetime-format localdate


【解决方案1】:

DateTimeFormatterBuilder.appendValue(TemporalField, int)

我惊讶地发现这是可能的(这对我来说没有多大意义)。

    DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.DAY_OF_MONTH, 1)
            .appendValue(ChronoField.MONTH_OF_YEAR, 1)
            .appendValue(ChronoField.YEAR, 4)
            .toFormatter();

    String dateOfBirth = "312015";
    LocalDate dateTime = LocalDate.parse(dateOfBirth, dateFormatter);
    System.out.println(dateTime);

这个 sn-p 的输出是:

2015-01-03

不过,它有一些我认为非常严重的限制:它只能解析 1 月到 9 月(不是 10 月到 12 月)的月份 1 到 9 天(不是 10 到 31 天)内的日期,因为它坚持月份和月份中的每一天只有一位数字。

您可以通过在第一次调用appendValue() 时省略第二个参数1 来摆脱对日期的限制。类似的技巧不会在本月起作用,因此今年的最后一个季度是遥不可及的。

为什么单 d 和单 M 不起作用?

为什么强制执行单个 d 和单个 M 在这里不起作用?我失踪了吗 这里有什么?

对于DateTimeFormatter,数字字段的一个模式字母表示“尽可能多的数字”(而不是预期的“1 位”)。它没有很好的记录。文档中有这句话的提示:

如果字母数为 1,则使用 最少位数且无填充。

发生的情况是,解析会在一个月中的某一天(最多为 19 个内部限制)吃尽可能多的数字。在这种情况下,整个字符串。现在它无法解析任何月份。这是错误信息的原因:

无法在索引 6 处解析文本“312015”

索引 6 是字符串的结尾。

文档链接

Documentation of DateTimeFormatter

【讨论】:

  • 感谢 Ole V.V.!这个解决方案就像一个魅力!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多