Возвращение ZonedDateTime всегда из Java TemporalAccessor с пропущенными полями - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть определенный класс, который анализирует (довольно) большое разнообразие дат:

// 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
    }
}

Я хотел бы вернуть ZonedDateTime, который имеет нормальные значения по умолчанию, если parsedString не полный ZonedDateTime.

  1. Скажем, например, что строка, заданная методу, равна "5:45pm" (которая будет успешно проанализирована); Я хотел бы, чтобы ZonedDateTime отображал 5:45 вечера сегодня в текущем часовом поясе. Конечно, более упреждающим способом было бы отразить 5:45 вечера следующего дня, если сегодня уже четверть шестого, но я бы хотел, чтобы это было реализовано первым.

  2. Другими возможными входными данными являются только день недели, например, "Monday": это вернет ZonedDateTime, установленное для следующего понедельника после текущего дня, в 12 часов по местному времени. зона.

  3. Ввод только даты "4/2/2020" вернул бы ZonedDateTime, установленный в местном часовом поясе, дату на входе (4 февраля 2020 г.) со временем установить в 12 часов вечера.

Как мне go сделать это? В настоящее время у меня есть немного кода, который состоит из очень длинной цепочки 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).

Кроме того, можно собрать a ZonedDateTime из parsedString, перебирая его поля, как-нибудь? Или есть какой-то другой способ реализовать всю эту идею разбора?

Спасибо всем.

1 Ответ

1 голос
/ 04 февраля 2020

Я не думаю, что вы можете сделать это только с шаблоном, но вы можете создать 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...