Q:

Outputting the day period based on locale

I want to format a date, which should be localized and includes the "day period".
"Day period" meaning not am/pm but "afternoon", "early morning" etc.
A formatted date based on german locale with the 12 hour setting enabled should look like 03.08.18, 9:01 abends, "abends" meaning evening.
The same example should be 3/8/18 9:01 de la noche in spanish.

Why i think it should be possible:
A: Because the WhatsApp Android app formats dates like this
B: Because the Java 10 source code includes the following (From the german translation file):
<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>

I tried: (current is the locale)
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);

String formattedDate = df.format(System.currentTimeMillis());

Output: 08.12.18 7:24 nachm or 8/12/18 7:54 p. m.

The following code has the same output: 
DateFormat abc = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, current);

abc.format(System.currentTimeMillis());

I also tried the 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);

Output: 8 dic. 2018 19:54p. m.p. m.p. m.11

Is there any way i can output the date this way?
Thanks

A:

There are only two libraries which support day periods, namely ICU4J (partially incorporated in Android) and my lib Time4A. Other formatters like java.text.DateFormat or java.time.format.DateTimeFormatter have no support.
Example in Time4A for the German locale (here with a bridge to the old-fashioned type 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()));

example output => "11.12.2018, 6:03 morgens"
It uses the special pattern symbol "B" defined by LDML-syntax of CLDR-data (managed by Unicode consortium). The day partition rules are also taken from CLDR data and look for German like:
# 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

If you don't agree with these data then you might construct your own customized formatter via the builder pattern.
Note about ICU4J: I have not tested that lib but maybe its class com.ibm.icu.text.SimpleDateFormat supports the pattern symbol B, too (but then the javadoc is outdated).
Another note:
If you like style-based formatting without specifying a concrete pattern then you might go this way using a composition of date and time part:
    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"

