Java 8 DateTimeFormatter синтаксический анализ для необязательных дробных секунд различной значимости - программирование

Java 8 DateTimeFormatter синтаксический анализ для необязательных дробных секунд различной значимости

My MCVE (как TestNG unit test ):

public class MyDateTimeFormatterTest {

    private static final String BASE_PATTERN = "yyyy/MM/dd HH:mm:ss";
    private static final DateTimeFormatter FORMATTER =
            DateTimeFormatter.ofPattern(BASE_PATTERN + "[.SSSSSSSSS]");
    private static final LocalDateTime TEST_INPUT =
            LocalDateTime.of(2015, 5, 4, 12, 34, 56, 123456789);

    @DataProvider(name = "test-cases")
    public Iterator<Object[]> getTestCases() {
        return Arrays.asList(testFor("", ChronoUnit.SECONDS),
                testFor(".SSS", ChronoUnit.MILLIS),
                testFor(".SSSSSS", ChronoUnit.MICROS),
                testFor(".SSSSSSSSS", ChronoUnit.NANOS)).iterator();
    }

    @Test(dataProvider = "test-cases")
    public void testWithDefaultResolution(String input, LocalDateTime output) {
        assertThat(FORMATTER.parse(input, LocalDateTime::from), equalTo(output));
    }

    private Object[] testFor(String patternSuffix, TemporalUnit truncatedTo) {
        return new Object[] { DateTimeFormatter.ofPattern(BASE_PATTERN + patternSuffix)
                .format(TEST_INPUT), TEST_INPUT.truncatedTo(truncatedTo) };
    }
}

Я пытаюсь проверить синтаксический анализ даты String с необязательными дробными секундами различной значимости, используя DateTimeFormatter. Соответствующая часть Джавадока гласит:

Фракция: выводит поле nano-of-second как долю секунды. Значение nano-of-second имеет девять цифр, поэтому количество букв шаблона составляет от 1 до 9. Если оно меньше 9, то значение nano-of-second усекается, и выводятся только самые значащие цифры.

Основываясь на моем ограниченном понимании, я использовал [...], чтобы отметить дробные секунды как необязательные, и поскольку меня интересует различное значение, я думал, что должен придерживаться SSSSSSSSS.

Однако unit test не работает при разборе до миллисекунд и микросекунд, то есть во втором и третьем случаях. Изменение ResolverStyle на LENIENT здесь не помогает, поскольку он не работает на этапе синтаксического анализа, а не в разрешении.

Могу ли я узнать, какие подходы следует рассмотреть, чтобы решить мою проблему? Должен ли я использовать DateTimeFormatterBuilder, чтобы опционально указать каждую дробную цифру (9 раз) или есть более "умный" способ с моим шаблоном?

edit Я нашел свой собственный ответ в конце... все равно оставит это без ответа в течение дня и посмотрю, есть ли другие подходы или нет.

4b9b3361

Ответ 1

О, круто, еще 15 минут устранения неполадок дали следующее:

private static final DateTimeFormatter FORMATTER = 
    new DateTimeFormatterBuilder().appendPattern(BASE_PATTERN) // .parseLenient()
        .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true).toFormatter();

изменить parseLenient() необязательно.