Как отформатировать момент в определенном месте в определенном часовом поясе для человека - PullRequest
0 голосов
/ 25 мая 2020

Я использую:

Locale locale = Locale.FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(locale).withZone(zone);
System.out.println(formatter.format(Instant.now()));

Результат, который я получаю: lundi 25 mai 2020 20 h 21 CEST с Locale.FRENCH и Monday, May 25, 2020 8:05:11 PM CEST с Locale.English

Я обнаружил, что CEST не быть удобным для не ИТ-специалистов, как я могу надежно удалить его?

Изменить

Я не хочу, чтобы CLDR был включен, мои пользователи уже знают в какой они стране, чтобы мы могли безопасно удалить информацию о часовом поясе.

Я должен иметь возможность работать с AN / PM и 24-часовым форматом, не перечисляя все страны.

Как это возможно?

Ответы [ 3 ]

2 голосов
/ 25 мая 2020

Exploit CLDR

Я понимаю, что вы используете Java 8, и на моем Java 8 я могу воспроизвести ваши результаты. Чтобы избежать недружественного пользователю сокращения CEST (и аналогичного для других часовых поясов), я предлагаю вам использовать CLDR, Unicode Common Locale Data Repository.

Либо запустите вашу программу Java с этим аргументом JVM: -Djava.locale.providers=CLDR.

Или установите системное свойство из вашей программы:

    System.setProperty("java.locale.providers", "CLDR");

Это изменит ваш вывод. Теперь при использовании французской локали вывод будет:

lundi 25 mai 2020 21:06:07 heure avancée d'Europe centrale

И на английском sh:

Понедельник, 25 мая 2020 г., 21:09:39 Летнее время по Центральной Европе

Как это работает? Java получает данные о своей локали, включая форматы даты и времени, используемые в разных регионах, из максимум четырех источников. В версиях до Java 8 включительно по умолчанию используются собственные локальные данные Java; но значение по умолчанию изменяется с помощью упомянутого системного свойства. В Java 9 и более поздних версиях по умолчанию используется CLDR ( JEP 252 ). Таким образом, внесение этого изменения для использования CLDR в Java 8 также подготовит вас к переходу на Java 9 или новее.

Чтобы полностью исключить часовой пояс

Я хочу удалите часовой пояс, поскольку пользователь уже знает, что он [в часах] - это страна.

Попутное примечание: в некоторых случаях пользователям нравится быть уверенным, что они получают время самостоятельно часовой пояс. Это также поможет устранить неоднозначность в случае, если вам нужно напечатать время в перекрытии падения, когда часы повернуты назад. heure avancée d’Europe centrale будет напечатано перед изменением часов, а heure normale de l’Europe centrale после него.

Конечно, вы лучше знаете, что ваши пользователи хотят и в чем нуждаются. Итак, есть несколько вариантов:

  1. Вручную удалить часовой пояс из шаблона формата, как показано в ответе от munge.
  2. Используйте FormatStyle.MEDIUM. Это уже было предложено в теперь удаленном ответе Дэдпула. Вы можете использовать разные стили формата для даты и времени:

        DateTimeFormatter formatter = DateTimeFormatter
                .ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM)
                .withLocale(locale)
                .withZone(zone);
        System.out.println(formatter.format(Instant.now()));
    

    Пример вывода на французском языке на Java 8:

    mardi 26 мая 2020 19:26:59

    И на английском sh locale:

    Вторник, 26 мая 2020 г., 19:27:26

2 голосов
/ 25 мая 2020

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

Locale locale = Locale.FRENCH;
Instant instant = Instant.now();

String pattern = getPatternWithoutTimezone(FormatStyle.FULL, Chronology.from(instant), locale);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern).withLocale(locale)
    .withZone(TimeZone.getDefault().toZoneId());
System.out.println(formatter.format(Instant.now()));

...

 private String getPatternWithoutTimezone(FormatStyle style, Chronology chronology,
  Locale locale) {
String pattern = java.time.format.DateTimeFormatterBuilder
    .getLocalizedDateTimePattern(FormatStyle.FULL, FormatStyle.FULL, chronology, locale);

/* remove time zone from pattern 
 * (see spec of "Date and time pattern" in Javadoc of java.text.SimpleDateFormat class)
 */
return pattern.replaceAll("[zZX]", "");

}

Обратите внимание, что .withLocale (locale) по-прежнему требуется, в противном случае вы использовали бы только формат, специфичный для локали c, но не локализованные названия дней, месяцев и т. Д. c.

1 голос
/ 25 мая 2020

вы можете настроить, что вы хотите показывать, а что нет, например, DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy hh:mm:ss a") дает lundi, mai 25, 2020 07:02:57 PM

...