Java8 эквивалент JodaTime DateTimeFormat.shortDate () - PullRequest
1 голос
/ 30 сентября 2019

Что такое Java8 java.time эквивалент

org.joda.time.formatDateTimeFormat.shortDate()

Я пробовал ниже путь, но он не в состоянии анализировать значения, такие как "20/5/2016" или "20/5/16".

DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) 

Ответы [ 2 ]

4 голосов
/ 30 сентября 2019

Вы правы: 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]");
  1. Он охватывает больше случаев, чем ваш форматтер Joda-Time. Может это и хорошо. В частности ваш форматировщик Joda-Time настаивает на косой черте / между числами и отклоняет либо дефис, точку или пробел. Также я полагаю, что Joda-Time будет возражать против того, чтобы год был пропущен полностью.
  2. Хотя вам нужно [yyyy][yy], вам не нужно [d][dd] или [M][MM]. Достаточно просто d и M, поскольку они также принимают две цифры (в вашем коде происходит то, что, например, [d] анализирует одну или две цифры, поэтому [dd] никогда не используется).
  3. Если вы предпочитаете только одну строку шаблона формата, я ожидаю, что d[/][-][.][ ]M[/][-][.][ ][yyyy][yy] будет работать (за исключением случаев, когда год пропущен) (я не проверял).
2 голосов
/ 30 сентября 2019

FormatStyle.SHORT возвращает кратчайший формат либо dd/MM/yy, либо d/M/yy, поэтому вам нужно использовать шаблон для получения настроенного формата

LocalDate date = LocalDate.now();   
System.out.println(date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));   //9/29/19

. Вы также можете использовать DateTimeFormatter.ISO_DATE или DateTimeFormatter.ISO_LOCAL_DATEчтобы получить формат ISO, такой как yyyy-MM-dd, а также вы можете увидеть доступные форматы в DateTimeFormatter

System.out.println(date.format(DateTimeFormatter.ISO_DATE));       //2019-09-29
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); //2019-09-29

Если вы хотите пользовательский формат, такой как yyyy/MM/dd, используйте ofPattern

System.out.println(date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))); //2019/09/29
...