Summary
-------
Support `Day Periods` defined in CLDR.
Problem
-------
Currently, the only day periods supported in the JDK are am/pm. In CLDR, there are other types of day periods, such as "midnight" or "noon" which have universally fixed interpretation, or "in the morning" in which the period definition differs across locales. Since version 33 of CLDR, some locales have introduced these day periods, which JDK has yet to be able to support.
Solution
--------
Introduce a new pattern character "`B`" that represents the `period-of-day`, which can be used in `java.time.DateTimeFormatter(Builder)` classes. A new method that corresponds to this pattern character will also be provided.
Specification
-------------
Add the following new pattern character definition in `java.time.format.DateTimeFormatter` class description:
@@ -300,6 +300,7 @@
* <tr><th scope="row">F</th> <td>day-of-week-in-month</td> <td>number</td> <td>3</td>
*
* <tr><th scope="row">a</th> <td>am-pm-of-day</td> <td>text</td> <td>PM</td>
+ * <tr><th scope="row">B</th> <td>period-of-day</td> <td>text</td> <td>in the morning</td>
* <tr><th scope="row">h</th> <td>clock-hour-of-am-pm (1-12)</td> <td>number</td> <td>12</td>
* <tr><th scope="row">K</th> <td>hour-of-am-pm (0-11)</td> <td>number</td> <td>0</td>
* <tr><th scope="row">k</th> <td>clock-hour-of-day (1-24)</td> <td>number</td> <td>24</td>
Similarly, add the following new pattern character definition in `java.time.format.DateTimeFormatterBuilder#appendPattern(pattern)` method:
```
@@ -1508,10 +1546,11 @@
* E day-of-week text Tue; Tuesday; T
* e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
* F day-of-week-in-month number 3
*
* a am-pm-of-day text PM
+ * B period-of-day text in the morning
* h clock-hour-of-am-pm (1-12) number 12
* K hour-of-am-pm (0-11) number 0
* k clock-hour-of-day (1-24) number 24
*
* H hour-of-day (0-23) number 0
@@ -1674,10 +1713,19 @@
* ZZZ 3 appendOffset("+HHMM","+0000")
* ZZZZ 4 appendLocalizedOffset(TextStyle.FULL)
* ZZZZZ 5 appendOffset("+HH:MM:ss","Z")
* </pre>
* <p>
+ * <b>Day periods</b>: Pattern letters to output a day period.
+ * <pre>
+ * Pattern Count Equivalent builder methods
+ * ------- ----- --------------------------
+ * B 1 appendDayPeriodText(TextStyle.SHORT)
+ * BBBB 4 appendDayPeriodText(TextStyle.FULL)
+ * BBBBB 5 appendDayPeriodText(TextStyle.NARROW)
+ * </pre>
+ * <p>
* <b>Modifiers</b>: Pattern letters that modify the rest of the pattern:
* <pre>
* Pattern Count Equivalent builder methods
* ------- ----- --------------------------
* [ 1 optionalStart()
```
Add a new method in `java.time.format.DateTimeFormatterBuilder` class:
/**
* Appends the day period text to the formatter.
* <p>
* This appends an instruction to format/parse the textual name of the day period
* to the builder. Day periods are defined in LDML's
* <a href="https://unicode.org/reports/tr35/tr35-dates.html#dayPeriods">"day periods"
* </a> element.
* <p>
* During formatting, the day period is obtained from {@code HOUR_OF_DAY}, and
* optionally {@code MINUTE_OF_HOUR} if exist. It will be mapped to a day period
* type defined in LDML, such as "morning1" and then it will be translated into
* text. Mapping to a day period type and its translation both depend on the
* locale in the formatter.
* <p>
* During parsing, the text will be parsed into a day period type first. Then
* the parsed day period is combined with other fields to make a {@code LocalTime} in
* the resolving phase. If the {@code HOUR_OF_AMPM} field is present, it is combined
* with the day period to make {@code HOUR_OF_DAY} taking into account any
* {@code MINUTE_OF_HOUR} value. If {@code HOUR_OF_DAY} is present, it is validated
* against the day period taking into account any {@code MINUTE_OF_HOUR} value. If a
* day period is present without {@code HOUR_OF_DAY}, {@code MINUTE_OF_HOUR},
* {@code SECOND_OF_MINUTE} and {@code NANO_OF_SECOND} then the midpoint of the
* day period is set as the time in {@code SMART} and {@code LENIENT} mode.
* For example, if the parsed day period type is "night1" and the period defined
* for it in the formatter locale is from 21:00 to 06:00, then it results in
* the {@code LocalTime} of 01:30.
* If the resolved time conflicts with the day period, {@code DateTimeException} is
* thrown in {@code STRICT} and {@code SMART} mode. In {@code LENIENT} mode, no
* exception is thrown and the parsed day period is ignored.
* <p>
* The "midnight" type allows both "00:00" as the start-of-day and "24:00" as the
* end-of-day, as long as they are valid with the resolved hour field.
*
* @param style the text style to use, not null
* @return this, for chaining, not null
* @since 16
*/
public DateTimeFormatterBuilder appendDayPeriodText(TextStyle style)
Add the following sentence to the field description of `java.time.temporal.ChronoField#AMPM_OF_DAY`:
@@ -333,10 +333,9 @@
* When parsing this field it behaves equivalent to the following:
* The value is validated from 0 to 1 in strict and smart mode.
* In lenient mode the value is not validated. It is combined with
- * {@code HOUR_OF_AMPM} to form {@code HOUR_OF_DAY} by multiplying
- * the {@code AMPM_OF_DAY} value by 12.
+ * {@code HOUR_OF_AMPM} (if not present, it defaults to '6') to form
+ * {@code HOUR_OF_DAY} by multiplying the {@code AMPM_OF_DAY} value
+ * by 12.
*/