【问题标题】:Create ZonedDateTime values with default values causes DateTimeParseException使用默认值创建 ZonedDateTime 值会导致 DateTimeParseException
【发布时间】:2020-06-10 21:56:14
【问题描述】:

我的目标是创建一个从字符串解析日期的方法,字符串和模式都作为参数给出,但是一些日期字符串不包含任何时间值,所以在我的方法中我将默认时间值设置为当前时间值存储在变量'now'中,但我在解析像这样10 may 2020 7:15 am这样的日期时遇到了一些麻烦。我用来解析日期的代码如下所示

    @Test 
    public void patronFechaZDT(){
    String strFecha = "10 may 2020 7:15 am";
    ZonedDateTime now = ZonedDateTime.now();
            DateTimeFormatter dtf1 = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("dd MMMM yyyy h:mm a")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, now.getMinute())
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, now.getSecond())
            .toFormatter(Locale.US)
            .withZone(ZoneId.systemDefault());

    TemporalAccessor accessor = dtf1.parse(strFecha, new ParsePosition(0));
    ZonedDateTime fecha = ZonedDateTime.from(accessor);

    System.out.println("str: " + strFecha + ", fecha: " + fecha );
}

上面代码的输出是

java.time.format.DateTimeParseException: Text '10 may 2020 7:15 am' could not be parsed: Conflict found: HourOfDay 16 differs from HourOfDay 7 while resolving  AmPmOfDay

我已经注意到问题是默认值 'HOUR_OF_DAY' 导致与字符串中捕获的小时冲突,并删除行 .parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour()),我的代码运行良好

主要问题是我的方法会接收很多模式和字符串,其中一些模式不包含时间值或区域值,我真的想使用默认时间值解析日期,所以如果它可以吗,我想保留.parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour()) 的线路,提前致谢。

编辑

正如@akuzminykh 所建议的,我添加了正确的 ChronoField CLOCK_HOUR_OF_AMPM,我的 DateTimeFormatter 现在看起来像这样:

    int hour = now.getHour(); int am = 0;
    if(hour > 12){
        hour = hour - 12;
        am = 1;
    }

    DateTimeFormatter dtf1 = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("dd MMMM yyyy hh:mm a")
            .parseDefaulting(ChronoField.AMPM_OF_DAY, am)
            .parseDefaulting(ChronoField.CLOCK_HOUR_OF_AMPM, hour)
            .parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, now.getMinute())
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, now.getSecond())
            .toFormatter(Locale.US)
            .withZone(ZoneId.systemDefault());

但是,除非我注释 .parseDefaulting(ChronoField.HOUR_OF_DAY... 行,否则这个新的格式化程序会产生相同的异常。任何帮助将不胜感激

【问题讨论】:

    标签: java date zoneddatetime


    【解决方案1】:

    当您解析h,即clock-hour-of-am-pm (1-12)(参见DateTimeFormatter)时,您当然必须使用正确的@ 987654325@ 为您的parseDefaulting。查看ChronoField。你需要的是ChronoField.CLOCK_HOUR_OF_AMPM

    【讨论】:

    • 哦,我现在明白了!!,有一种方法可以在同一个 Builder 中为 CLOCK_HOUR_OF_AMPM 和 ChronoField.HOUR_OF_DAY 设置默认值?例如,如果在 String 中找到 hh 的值,则忽略 HH 的默认值?
    • @FernandoCT 当然可以。格式化程序将采用模式指定的任何内容。
    • 好的,我添加了正确的默认 ChronoField.CLOCK_HOUR_OF_AMPM,除非我删除 HOUR_OF_DAY 的默认值,否则问题仍然存在,我编辑我的问题,如果你能再赶上会很棒
    • @FernandoCT 我在评论中不太清楚:就正确的模式而言,您可以同时使用两者,但不能同时使用两者。当你同时拥有两者时,格式化程序如何决定时间应该是多少?这正是错误告诉您的内容。当您的模式已经提供了来自h 的小时信息时,它应该如何处理H 的默认值?这就是问题所在,您基本上需要两个不同的时间来创建ZonedDateTime。现在清楚了吗?
    猜你喜欢
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多