DateTimeFormatter слишком строг в разборе однозначных частей - PullRequest
0 голосов
/ 29 мая 2018

У меня есть формат MM/dd/yyyy, так что все отформатировано с начальным нулем на одной цифре.Проблема в том, что при разборе я хочу иметь возможность анализировать и "11/25/2018", и "5/25/2018", но форматирование всегда должно возвращать ведущие нули.

Я безуспешно пытался использовать разные опции ResolverStyle.

Создание моего собственного специфического формата кажется неразумным, когда вы думаете, что оно работало «из коробки» с использованием SimpleDateFormat.

Буду признателен за любую идею, которая не предполагает создание форматера с нуля.используя FormatterBuilder

Ответы [ 4 ]

0 голосов
/ 29 мая 2018

Вы можете использовать appendOptional() в Java 8 time API

DateTimeFormatter ALL_POSSIBLE_DATE_FORMAT = new DateTimeFormatterBuilder()
            .appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
            .appendOptional(DateTimeFormatter.ofPattern(("M/dd/yyyy")))
            .toFormatter();

System.out.println(LocalDate.parse("11/25/2018", ALL_POSSIBLE_DATE_FORMAT));
System.out.println(LocalDate.parse("5/25/2018", ALL_POSSIBLE_DATE_FORMAT));

Вывод:

2018-11-25

2018-05-25

0 голосов
/ 29 мая 2018

Используйте два разных формата: M/d/yyyy для анализа и MM/dd/yyyy для печати.Первый будет принимать как однозначные, так и двузначные месяцы и дни, в то время как последние всегда будут печатать двузначные числа с начальным нулем, если необходимо.

SimpleDateFormat parseFormat = new SimpleDateFormat("M/d/yyyy");
SimpleDateFormat printFormat = new SimpleDateFormat("MM/dd/yyyy");

Date date1 = parseFormat.parse("4/5/2010");
Date date2 = parseFormat.parse("04/05/2010");
String output1 = printFormat.format(date1);
String output2 = printFormat.format(date2);
// output1 and output2 will be the same
0 голосов

Используйте формат M/d/yyyy, потому что начальные нули игнорируются.MM/dd/yyyy подразумевает, что требуется ровно две цифры, включая возможный начальный ноль.

    DateTimeFormatter parseformat =
            DateTimeFormatter.ofPattern("M/d/yyyy");

    DateTimeFormatter outputformat = DateTimeFormatter.ofPattern("MM/dd/yyyy");

Для сегмента кода

    String d1 = "1/1/2018";
    String d2 = "02/29/2016";
    String d3 = "4/01/2018";

    LocalDate date = LocalDate.parse(d1, parseformat);
    System.out.println(date.format(outputformat));
    date = LocalDate.parse(d2, parseformat);
    System.out.println(date.format(outputformat));
    date = LocalDate.parse(d3, parseformat);
    System.out.println(date.format(outputformat));

Я получил

01/01/2018
02/29/2016
04/01/2018

как и ожидалось.

См. Документацию SimpleDateFormat для временных шаблонов и того, как они анализируются;обратите внимание, что «буквы шаблона обычно повторяются, так как их число определяет точное представление» и что «при разборе количество букв шаблона игнорируется, если только не требуется разделять два смежных поля» (здесь вы разделяете два смежных поля).

0 голосов
/ 29 мая 2018

Вам нужно использовать M / d / yyyy.Он будет работать как с однозначными, так и с двойными цифрами.Когда вы используете MM / dd, вы указываете строго использовать две цифры.

Это из документов:

Число: Если количество букв равно одному, , тозначение выводится с использованием минимального количества цифр и без заполнения.В противном случае в качестве ширины поля вывода используется количество цифр, при необходимости значение заполняется нулями.Следующие буквы шаблона имеют ограничения на количество букв.Можно указать только одну букву «с» и «F».Можно указать до двух букв «d», «H», «h», «K», «k», «m» и «s».Можно указать до трех букв «D».

...