我有一个特定的类来解析(相当)多种日期:

// imports omitted for brevity

public final class DateParser
{
    private static final String DATE_TIME_FORMAT_PATTERN
            = "[h][hh][[:][.]mm][[ ]a][ v][ ][[EEEE ][E ][d][dd][/][-][LLLL][L][/][-][uuuu]]";

    private static final DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_PATTERN).localizedBy(Locale.ENGLISH);

    public static ZonedDateTime parseDateTimeString(final String dateTimeString)
    {
        TemporalAccessor parsedString = formatter.parse(dateTimeString);

        ZonedDateTime returnable = ZonedDateTime.now();

        // Return a ZonedDateTime with sane defaults if some fields are missing from parsedString
    }
}


如果parsedString不是完整的ZonedDateTime,我想返回具有默认值的ZonedDateTime


例如,假设给该方法的字符串是"5:45pm"(它将成功解析);我希望ZonedDateTime在当前时区反映今天下午5:45。当然,一种更抢占的方式是,如果今天已经过了四分之一到第二天,则在第二天下午5:45反映出来,但是我想首先实施。
其他可能的输入只是一周中的某天,例如"Monday":这将返回在当前时间后当地时间当地时间下午12点为下一个星期一设置的ZonedDateTime
仅输入日期"4/2/2020"会返回在本地时区设置的ZonedDateTime,即输入中的日期(2020年2月4日),时间设置为12 pm。


我将如何去做呢?我目前有一些代码,只包含很长的if链:

if (parsedString.isSupported(ChronoField.YEAR))
{
    returnable = returnable.withYear(parsedString.get(ChronoField.YEAR));
}
if (parsedString.isSupported(ChronoField.DAY_OF_MONTH))
{
    returnable = returnable.withMonth(parsedString.get(ChronoField.MONTH_OF_YEAR));
}
if (parsedString.isSupported(ChronoField.DAY_OF_MONTH))
{
    returnable = returnable.withDayOfMonth(parsedString.get(ChronoField.DAY_OF_MONTH));
}
// And so on.


但是,这仅修改了当前日期时间组。我不确定如何实现(2)和(3)之类的东西。

此外,可以通过遍历字段的方式以某种方式从ZonedDateTime构建parsedString吗?还是有其他方法可以实现整个解析想法?

谢谢大家。

最佳答案

我认为您不能仅使用模式来执行此操作,但是可以创建DateTimeFormatterBuilder并调用其parseDefaulting方法:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.appendPattern(DATE_TIME_FORMAT_PATTERN);

ZonedDateTime defaults = ZonedDateTime.now();

builder.parseDefaulting(ChronoField.YEAR,
       defaults.getLong(ChronoField.YEAR));
builder.parseDefaulting(ChronoField.MONTH_OF_YEAR,
       defaults.getLong(ChronoField.MONTH_OF_YEAR));
builder.parseDefaulting(ChronoField.DAY_OF_MONTH,
       defaults.getLong(ChronoField.DAY_OF_MONTH));
// etc.

DateTimeFormatter formatter = builder.toFormatter();

ZonedDateTime returnable = ZonedDateTime.parse(dateTimeString, formatter);

关于java - 总是从缺少字段的Java TemporalAccessor返回ZonedDateTime,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60045914/

10-10 02:03