Как получить форматирование даты в локали с определенным шаблоном? - PullRequest
0 голосов
/ 02 июля 2018

После поиска мне не удалось найти решение этой проблемы.

У меня есть это:

Long parseDt = Long.valueOf(arrayJson.getJSONObject(i-j).getInt("dt")); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String date = new SimpleDateFormat("EEE d MMM", locale).format(new java.util.Date(parseDt * 1000));

Итак, шаблон работает, но когда я меняю язык телефона, он не поменял местами способ отображения, я хочу иметь в виду, что если язык телефона французский, он отображает такую ​​дату, и это хорошо для большинства европейский язык:

Лун 2 июля

и если я переключаю язык на английский, отображается такая дата:

пн 2 июля

вместо:

понедельник 2

Есть ли у вас какие-либо подсказки, чтобы решить эту проблему в отношении моего паттерна, зная, что мне нужно название дня с максимум 3 символами?

Существующий предопределенный формат (например, FULL) может работать, но название дня отображается полностью, например, это «понедельник», и я хотел бы только «понедельник», а не «понедельник», так что, есть идеи?

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Java уже «знает», в каких локалях день месяца идет перед названием месяца и в котором он идет после. Это то, что дал вам полный предопределенный формат. Поэтому для общего решения, которое может работать во всех или в большинстве регионов, я полагаю, что вы на это полагаетесь Мы можем изменить предопределенный полный шаблон, чтобы использовать сокращения для дня недели и месяца:

    int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
    Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
    String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.FULL, null, IsoChronology.INSTANCE, locale);
    formatPattern = formatPattern.replaceAll("E{3,}", "EEE").replaceAll("M{3,}", "MMM");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern, locale);
    ZoneId zone = ZoneId.of("America/Whitehorse");
    ZonedDateTime dateTime = Instant.ofEpochSecond(parseDt).atZone(zone);
    String date = dateTime.format(dateFormatter);
    System.out.println(date);

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

  • В Великобритании: Mon, 2 Jul 2018
  • В США: Mon, Jul 2, 2018
  • Во французском языке: lun. 2 juil. 2018

Я использую регулярные выражения, чтобы убедиться, что если день недели и / или месяц указан в строке шаблона формата (например, EEEE и MMMM), он будет изменен на его сокращение. Поскольку день недели также может быть указан строчными буквами e или c, а месяц - L, вы можете сделать то же самое с этими буквами.

Я использую java.time, современный Java API даты и времени. Чтобы использовать это на не совсем новом Android, получите библиотеку ThreeTenABP: используйте ссылки внизу. Если вы возражаете против использования высококачественной внешней библиотеки, ориентированной на будущее, вы можете сыграть подобный трюк с SimpleDateFormat.

Если вы тоже хотите пропустить год (как в ваших примерах), это немного сложнее, но выполнимо. Вот простая попытка удалить год, если он наступит последним:

    formatPattern = formatPattern.replaceFirst("^(.*[\\w'])([^\\w']*y+)$", "$1");

С этой вставленной строкой вывод во французском языке, например, lun. 2 juil.. Год можно также указать буквой u, вы также можете принять это во внимание.

Преобразование вашего времени Unix в дату является чувствительной к часовому поясу операцией, поэтому я даю часовой пояс в коде. Пожалуйста, поместите тот, который вы хотите, где я положил Америку / Whitehorse. Если вы уверены, что настройка часового пояса JVM отражает то, что хочет пользователь, вы можете использовать ZoneId.systemDefault() (SimpleDateFormat в вашем собственном коде также использует настройку VM).

Ссылки

0 голосов
/ 03 июля 2018

В соответствии с форматом даты стран:

https://en.wikipedia.org/wiki/Date_format_by_country

и моему приложению нужен самый простой способ его отображения:

int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String dateFormat = ((locale.equals(Locale.US) || locale.equals(Locale.CHINA) || locale.equals(Locale.CANADA) || locale.equals(Locale.JAPAN)) ? "EEE, MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(dateFormat, locale).format(new java.util.Date(parseDt * 1000));
0 голосов
/ 02 июля 2018

Вы можете переключать формат в зависимости от локали, которую вы получили.

Locale locale = ConfigurationCompat.getLocales(
                   Resources.getSystem().getConfiguration()).get(0);

String fmt = (locale == Locale.ENGLISH) ? "EEE MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(fmt, locale)
                   .format(new java.util.Date(parseDt * 1000));
...