使用默认值创建 ZonedDateTime 值会导致 DateTimeParseException

Create ZonedDateTime values with default values causes DateTimeParseException

我的目标是创建一个从字符串中解析日期的方法,字符串和模式都作为参数给出,但是一些日期字符串不包含任何时间值,所以在我的方法中我将默认时间值设置为当前时间值存储在变量 '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()),我的代码运行良好

主要问题是我的方法会收到很多模式和字符串,其中一些模式不包含时间值或时区值,我真的想使用默认时间值解析日期,所以如果它是 posile 我想保留这条线 .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... 进行注释,否则这个新的 Formatter 会产生相同的异常。任何帮助都将不胜感激

当您解析 h 时,它对应于 clock-hour-of-am-pm (1-12)(参见 DateTimeFormatter), you of course have to use the correct ChronoField for your parseDefaulting. Check out ChronoField。什么你需要的是 ChronoField.CLOCK_HOUR_OF_AMPM.