Java 8 Как исключить необязательные части при использовании формата DateTimeFormatter # - PullRequest
0 голосов
/ 27 ноября 2018

Я использую Java 8 DateTimeFormatter с шаблоном, который имеет необязательную часть, и я хочу, чтобы эта необязательная часть была исключена при форматировании в String

Шаблон, который я использую: yyyyMMddHHmmss[.SSS]Z

Как я использую мой DateTimeFormatter:

DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss[.SSS]Z");
String formattedDate = df.format(zonedDateTime);

Я ожидаю, что результат будет: 20180606052500+0100

Вместо: 20180606052500.000+0100

Решением будет использование двух DateTimeFormatter, но я не хочу этого, поскольку хочу, чтобы мой DateTimeFormatter был статически определен в одном месте, чтобы его можно было повторно использовать как для синтаксического анализа, так и для форматирования.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Возможным решением является использование DateTimeFormatterBuilder и его appendFraction метода:

    DateTimeFormatter df = new DateTimeFormatterBuilder()
            .appendPattern("yyyyMMddHHmmss")
            .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
            .appendPattern("Z")
            .toFormatter(Locale.ROOT);
    OffsetDateTime odt = OffsetDateTime.parse("20180606052500+0100", df);
    String formattedDate = df.format(odt);
    System.out.println(formattedDate);

Вывод:

20180606052500 + 0100

Таким образом, код проанализировал вариант без доли секунды и отформатировал обратно таким же образом.Если он анализирует "20180606052500.000+0100", он все равно не будет печатать дробь.С "20180606052500.125+0100" он также печатает 20180606052500.125+0100, то есть с дробью.

Я также пробовал с "20180606052500.100+0100" и получил 20180606052500.1+0100.Так что в этом случае он печатает один десятичный знак.Возможно, вы хотели три знака после запятой в этом случае, я не знаю.appendFraction принимает минимальное и максимальное количество десятичных знаков, но нет способа указать, что 3 десятичных знака предпочтительнее, чем 1 или 2.

Если вы никогда не хотите печатать какую-либо дробь,независимо от того, является ли он нулевым или ненулевым, используйте:

    String formattedDate = df.format(odt.truncatedTo(ChronoUnit.SECONDS));

PS Поскольку у вас нет часового пояса (например, Австралия / Хобарт), используйте OffsetDateTime для даты-времени, а неZonedDateTime.

Ссылка на документ: DateTimeFormatterBuilder.appendFraction

0 голосов
/ 27 ноября 2018

Одним из простых решений является повторное использование общей части шаблона для создания 2 различных форматов:

private static final String META_FORMAT = "yyyyMMddHHmmss%sZ";
private static final DateTimeFormatter FOR_PARSING = DateTimeFormatter.ofPattern(String.format(META_FORMAT, "[.SSS]"));
private static final DateTimeFormatter FOR_FORMATTING = DateTimeFormatter.ofPattern(String.format(META_FORMAT, ""));

Таким образом, у вас нет дублирующего шаблона.

...