Шаблон SimpleDateFormat, основанный на локали, но с 4-значным годом - PullRequest
7 голосов
/ 17 октября 2011

Мне нужно создать формат даты, например dd/MM/yyyy.Это почти как DateFormat.SHORT, но содержит 4 года.

Я пытаюсь реализовать его с помощью

new SimpleDateFormat("dd//MM/yyyy", locale).format(date);

Однако для локали в США формат неправильный.

ЕстьЕсть ли общий способ форматирования даты, который меняет шаблон в зависимости от локали?

Спасибо

Ответы [ 4 ]

11 голосов
/ 17 октября 2011

Я бы сделал это так:

    StringBuffer buffer = new StringBuffer();

    Calendar date = Calendar.getInstance();
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
    FieldPosition yearPosition = new FieldPosition(DateFormat.YEAR_FIELD);

    StringBuffer format = dateFormat.format(date.getTime(), buffer, yearPosition);
    format.replace(yearPosition.getBeginIndex(), yearPosition.getEndIndex(), String.valueOf(date.get(Calendar.YEAR)));

    System.out.println(format);

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

Вы просто используете начальный и конечный индексы поля года и всегда заменяете его четырехзначным значением года, и все.

3 голосов
/ 18 июля 2017

java.time

Вот современный ответ. ИМХО в наши дни никто не должен бороться с давно устаревшими DateFormat и SimpleDateFormat классами. Их замена появилась в современном API даты и времени Java в начале 2014 года, java.time классы .

Я просто применяю идею из ответа Хаппира к современным классам.

Метод DateTimeFormatterBuilder.getLocalizedDateTimePattern создает шаблон форматирования для стилей даты и времени для Locale. Мы манипулируем результирующей строкой шаблона, чтобы заставить 4-значный год.

LocalDate date = LocalDate.of( 2017, Month.JULY, 18 );

String formatPattern =
    DateTimeFormatterBuilder.getLocalizedDateTimePattern(
        FormatStyle.SHORT, 
        null, 
        IsoChronology.INSTANCE, 
        userLocale);
formatPattern = formatPattern.replaceAll("\\byy\\b", "yyyy");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, userLocale);

String output = date.format(formatter);

Пример вывода:

  • Для Locale.US: 7/18/2017.
  • Для каждого из UK, FRANCE, GERMANY и ITALY: 18/07/2017.

DateTimeFormatterBuilder позволяет нам получить строку шаблона локализованного формата напрямую, без предварительного форматирования, это удобно здесь. Первый аргумент getLocalizedDateTimePattern() - это стиль формата даты. null в качестве второго аргумента указывает на то, что нам не нужен формат времени. В моем тесте я использовал LocalDate для date, но код должен работать и для других современных типов дат (LocalDateTime, OffsetDateTime и ZonedDateTime).

0 голосов
/ 27 февраля 2012

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

Так вот код

            // date format, always using yyyy as year display
        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
        SimpleDateFormat simple = (SimpleDateFormat) dateFormat;
        String pattern = simple.toPattern().replaceAll("\\byy\\b", "yyyy");
        System.out.println(pattern);
0 голосов
/ 17 октября 2011

Разве вы не можете просто использовать класс java.text.DateFormat?

DateFormat uk = DateFormat.getDateInstance(DateFormat.LONG, Locale.UK);
DateFormat us = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);

Date now = new Date();
String usFormat = us.format(now);
String ukFormat = uk.format(now);

Это должно делать то, что вы хотите.

...