Я хочу отформатировать дату, которая должна быть локализована и включать «дневной период».
«Дневной период» означает не утро / вечер, а «полдень», «раннее утро» и т. д.
Дата, отформатированная на немецком языке с включенной настройкой 12 часов, должна выглядеть как 03.08.18, 9:01 abends, что означает «abends», что означает вечер.
Тот же пример должен быть 3/8/18 9:01 de la noche на испанском языке.
A: Потому что приложение WhatsApp для Android использует такие форматы
B: Поскольку исходный код Java 10 включает следующее (из файла перевода на немецкий язык):
<dayPeriods>
<dayPeriodContext type = "format">
<dayPeriodWidth type = "wide">
<dayPeriod type = "afternoon">nachmittags</dayPeriod>
<dayPeriod type = "am">vorm.</dayPeriod>
<dayPeriod type = "earlyMorning">morgens</dayPeriod>
<dayPeriod type = "evening">abends</dayPeriod>
<dayPeriod type = "morning">vormittags</dayPeriod>
<dayPeriod type = "night">nachts</dayPeriod>
<dayPeriod type = "noon">Mittag</dayPeriod>
<dayPeriod type = "pm">nachm.</dayPeriod>
</dayPeriodWidth>
</dayPeriodContext>
...
</dayPeriods>
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);
String formattedDate = df.format(System.currentTimeMillis());
Выход: 08.12.18 7:24 nachm или 8/12/18 7:54 p. m.
DateFormat abc = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);
abc.format(System.currentTimeMillis());
DateTimeFormatterBuilder (With all of the AMPM_OF_DAY versions):
DateTimeFormatter test = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT);
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.append(test)
.appendText(ChronoField.AMPM_OF_DAY, TextStyle.SHORT)
.appendText(ChronoField.AMPM_OF_DAY, TextStyle.NARROW)
.appendText(ChronoField.AMPM_OF_DAY, TextStyle.FULL)
.appendText(ChronoField.AMPM_OF_DAY, TextStyle.FULL_STANDALONE)
.toFormatter(current);
ZonedDateTime date = ZonedDateTime.now();
date.format(fmt);
Выход: 8 dic. 2018 19:54p. m.p. m.p. m.11
Есть ли способ вывести дату таким образом?
Спасибо
Вы, безусловно, должны предпочесть современный DateTimeFormatter хлопотному и старомодному SimpleDateFormat.
@ OleV.V. Спасибо за твои мысли. Да, это проблема. Я хотел бы знать, как это делает WhatsApp. Я думаю, они просто используют правильный форматер даты Java или небольшой трюк, потому что вся необходимая информация находится в исходном коде Java. Юникод LDML определяет периоды. LDML - это спецификация, которую Java использует для локалей
Отвечает ли это на ваш вопрос? Отображение сообщения утром, днем, вечером, ночью на основе времени в java




Есть только две библиотеки, которые поддерживают дневные периоды, а именно ICU4J (частично встроена в Android) и моя библиотека Time4A. Другие форматеры, такие как java.text.DateFormat или java.time.format.DateTimeFormatter, не поддерживают.
Пример в Time4A для немецкого языка (здесь с мостом к старомодному типу java.util.Date):
ChronoFormatter<java.util.Date> f =
ChronoFormatter.ofPattern(
"dd.MM.uuuu, h:mm BBBB",
PatternType.CLDR,
Locale.GERMAN,
Moment.axis(TemporalType.JAVA_UTIL_DATE))
.withStdTimezone();
System.out.println(f.format(new java.util.Date()));
пример вывода => "11.12.2018, 6:03 моргенс"
Он использует специальный символ рисунка "B", определенный LDML-синтаксисом CLDR-данных (управляемый консорциумом Unicode). Правила дневного разделения также взяты из данных CLDR и выглядят для немецкого языка как:
# day-period-rules
T0000=night1
T0500=morning1
T1000=morning2
T1200=afternoon1
T1300=afternoon2
T1800=evening1
# day-period-translations
P(a)_morning1=morgens
P(a)_morning2=vormittags
P(a)_afternoon1=mittags
P(a)_afternoon2=nachmittags
P(a)_evening1=abends
P(a)_night1=nachts
Если вы не согласны с этими данными, вы можете создать свой собственный форматировщик с помощью шаблон строителя.
Примечание о ICU4J: я не тестировал эту библиотеку, но, возможно, ее класс com.ibm.icu.text.SimpleDateFormat также поддерживает символ шаблона B (но тогда javadoc устарел).
Другое примечание:
Если вам нравится форматирование на основе стилей без указания конкретного шаблона, вы можете пойти этим путем, используя композицию части даты и времени:
Locale loc = Locale.US;
// our concrete values to be formatted
Moment moment = SystemClock.currentMoment();
PlainDate calendarDate = moment.toLocalTimestamp().getCalendarDate();
// get the localized clock pattern
Map<String, String> textForms = CalendarText.getIsoInstance(loc).getTextForms();
String pattern =
textForms.containsKey("F_Bhm") ? textForms.get("F_Bhm") : "h:mm B";
// construct the style-based date formatter
ChronoFormatter<PlainDate> f1 =
ChronoFormatter.ofDateStyle(DisplayMode.SHORT, loc);
// construct the time formatter
ChronoFormatter<Moment> f2 = ChronoFormatter.ofMomentPattern(
pattern,
PatternType.CLDR,
loc,
Timezone.ofSystem().getID());
System.out.println(f1.format(calendarDate) + " " + f2.format(moment));
// example output => "12/11/18 6:18 in the morning"
Это уже было очень полезно. Есть ли способ получить шаблон даты и времени, как на выходах DateUtils.formatDateTime? В SimpleDateFormat и в ваших примерах отсутствует символ «,» (`12.12.2018, 1:13 nachm.`), который мне, к сожалению, нужен в зависимости от языкового стандарта (некоторые языковые стандарты включают его, а некоторые нет).
@Nick Я понимаю ваше желание локализованных литералов, сочетающих шаблоны даты и времени. К сожалению, Time4J / A еще не поддерживает это. Но я открыл новый выпуск, чтобы отслеживать любые предложения / предложения. Ваши предложения приветствуются. Если быть реалистом, из-за сложности окончательного решения не будет до весны 2019 года.
Основная проблема может заключаться в том, что разные культуры по-разному делят день, поэтому прямого перевода нет. У вас уже есть кое-что из этого в AM и PM, которые не используются в немецком языке. Я не знаю этого, но полагаю, что люди в Средиземном море ожидали бы «сиесты», которой нет в вашем списке. И так далее.