【问题标题】:Local date parsing not working without separators本地日期解析在没有分隔符的情况下不起作用
【发布时间】:2019-02-04 10:00:14
【问题描述】:

我的日期格式如下:

四位数的年份,然后是两位数的星期数。

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

我在使用 Java 8 的 LocalDateDateTimeFormatterBuilder 解析这些日期时遇到问题。

这是我尝试解析日期的方式:

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

执行抛出以下异常:

java.time.format.DateTimeParseException:无法在索引 0 处解析文本“201804”

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

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

结果:

2018-01-22

格式化程序有什么我遗漏的吗?

【问题讨论】:

  • 2018年第四周还是2019年??

标签: java java-8 datetime-format date


【解决方案1】:

您可以使用appendValue

此方法支持一种称为“相邻值解析”的特殊解析技术。该技术解决了一个值(可变宽度或固定宽度)后跟一​​个或多个固定长度值的问题。标准解析器是贪婪的,因此它通常会窃取紧随可变宽度一的固定宽度值解析器所需的数字。

启动“相邻值解析”不需要任何操作。当调用 appendValue 时,builder 进入相邻值解析设置模式。

所以这行得通:

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

【讨论】:

    【解决方案2】:

    尝试明确定义计时字段:

    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);
    

    【讨论】:

    • 好像不行,执行你的sn-p返回-596400000-01-17
    • @ThomasFerro Ups,这是一个错字。应该是 appendValue 而不是 appendFraction。更新了代码 sn-p。
    【解决方案3】:

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

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

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

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

    【讨论】:

    • 感谢您的提示,但在这种特殊情况下,我知道确切的格式“YYYYww”,而且我已经在使用 LocalDate 而不是 LocalTimeDate。
    • 对不起。但我仍然认为这种特殊格式的特殊性(与有一些免费格式相反)会给你带来问题。
    【解决方案4】:

    不会简单地做这项工作吗?

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

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

    【讨论】:

    • 不幸的是,将 DateTimeFormatter.of 更改为 DateTimeFormatter.ofPattern 会引发相同的异常:/
    • 不,不会的。
    • 已编辑,您只需将 1 附加到您正在解析的日期以使其选择该周的星期一,并使用 YYYYwwe
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 2016-07-04
    • 2017-04-10
    相关资源
    最近更新 更多