没有分隔符的本地日期解析不起作用

Local date parsing not working without separators

我的日期格式如下:

The year in four digits then the week number in two digits.

例如,2018 年的第四周将是 201804

我在使用 Java 8 的 LocalDateDateTimeFormatterBuilder.

解析这些日期时遇到问题

以下是我尝试解析日期的方法:

LocalDate.parse(
    "201804",
    new DateTimeFormatterBuilder().appendPattern("YYYYww").parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
);

执行抛出以下异常:

java.time.format.DateTimeParseException: Text '201804' could not be parsed at index 0

奇怪的是,当我在日期部分之间添加分隔符时,不再抛出异常:

LocalDate.parse(
    "2018 04",
    new DateTimeFormatterBuilder().appendPattern("YYYY ww").parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
);

结果:

2018-01-22

格式化程序是否遗漏了什么?

简单地做这个工作不行吗?

LocalDate.parse("2018041", DateTimeFormatter.ofPattern("YYYYwwe"));

本质上,您需要告诉它您想要那周 Monday 的日期,而不仅仅是那一周。

尝试明确定义计时字段:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter formatter = 
      builder.appendValue(ChronoField.YEAR, 4)
             .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2)
             .parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
             .toFormatter();

LocalDate.parse("201804", formatter);

是的,这也让我用国外来源的数据杀死了很多次....

根据您获得的内容,您需要不同的解析器。对于 Date 你需要 LocalDate,对于有时间的东西你需要 LocalTimedate.parse。

意思是如果你不知道你得到了什么数据(常见的是当天没有日期但有时间,另一方面过去的日期没有时间但有日期 - 所以你不知道),您必须首先自己进行粗略解析以检测特定格式,然后才 Java 解析它.... Javas 恕我直言,日期处理有点困难。

所以解决方案是:使用 LocalDate 而不是 LocalTimeDate。

您可以使用appendValue

This method supports a special technique of parsing known as 'adjacent value parsing'. This technique solves the problem where a value, variable or fixed width, is followed by one or more fixed length values. The standard parser is greedy, and thus it would normally steal the digits that are needed by the fixed width value parsers that follow the variable width one.

No action is required to initiate 'adjacent value parsing'. When a call to appendValue is made, the builder enters adjacent value parsing setup mode.

所以这有效:

LocalDate.parse(
                "201804",
                new DateTimeFormatterBuilder()
                        .appendValue(YEAR, 4)
                        .appendValue(ALIGNED_WEEK_OF_YEAR, 2)
                        .parseDefaulting(WeekFields.ISO.dayOfWeek(), 1).toFormatter()
        );