Вы правы: Joda-Time DateTimeFormatter
(это тип, который вы получаете от DateTimeFormat.shortDate()
) анализирует более мягко, чем java.time DateTimeFormatter
. В английской / новозеландской локали (en-NZ
) shortDate
использует шаблон формата d/MM/yy
и анализирует 20/5/2016
и 20/5/16
в 2016-05-20.
Я откровенно нахожу это противнымчто он интерпретирует как двузначные, так и четырехзначные годы в одном и том же году. Когда в формате указан год из двух цифр, я ожидал, что четыре цифры будут ошибкой для более строгой проверки ввода. Принятие однозначного месяца, когда формат задает две цифры, также мягко, но, возможно, не так опасно и больше соответствует тому, что мы можем ожидать.
java.time также использует шаблон формата d/MM/yy
(проверено наJDK-11.0.3). Когда синтаксический анализ принимает одну или две цифры для дня месяца, но настаивает на двухзначном месяце и двухзначном году.
Вы можете получить поведение Joda-Time в java.time, но оно требует от васукажите шаблон формата самостоятельно:
Locale loc = Locale.forLanguageTag("en-NZ");
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d/M/[yyyy][yy]", loc);
System.out.println(LocalDate.parse("20/5/2016", dateFormatter));
System.out.println(LocalDate.parse("20/5/16", dateFormatter));
Вывод:
2016-05-20
2016-05-20
Если вам нужно расширенное решение, которое работает в других локалях, я уверен, что выможет написать фрагмент кода, который получает шаблон формата из DateTimeFormatterBuilder.getLocalizedDateTimePattern
и изменяет его, заменяя dd
на d
, MM
на M
и любое число y
на [yyyy][yy]
. Затем передайте измененную строку шаблона формата на DateTimeFormatter.ofPattern
.
Редактировать: Я рад, что у вас есть что-то для работы. В своем комментарии вы сказали, что использовали:
Stream<String> shortFormPatterns = Stream.of(
"[d][dd]/[M][MM]",
"[d][dd]-[M][MM]",
"[d][dd].[M][MM]",
"[d][dd] [M][MM]",
"[d][dd]/[M][MM]/[yyyy][yy]",
"[d][dd]-[M][MM]-[yyyy][yy]",
"[d][dd].[M][MM].[yyyy][yy]",
"[d][dd] [M][MM] [yyyy][yy]");
- Он охватывает больше случаев, чем ваш форматтер Joda-Time. Может это и хорошо. В частности ваш форматировщик Joda-Time настаивает на косой черте
/
между числами и отклоняет либо дефис, точку или пробел. Также я полагаю, что Joda-Time будет возражать против того, чтобы год был пропущен полностью. - Хотя вам нужно
[yyyy][yy]
, вам не нужно [d][dd]
или [M][MM]
. Достаточно просто d
и M
, поскольку они также принимают две цифры (в вашем коде происходит то, что, например, [d]
анализирует одну или две цифры, поэтому [dd]
никогда не используется). - Если вы предпочитаете только одну строку шаблона формата, я ожидаю, что
d[/][-][.][ ]M[/][-][.][ ][yyyy][yy]
будет работать (за исключением случаев, когда год пропущен) (я не проверял).