JDK-8354363 : Date/time formatting in Java produces ambiguous results for 12:00 am and 12:00 pm
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.time
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2025-04-10
  • Updated: 2025-04-11
  • Resolved: 2025-04-11
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Applies across all operating systems and Java versions that include the java.time API. Locale formatting inconsistencies are inherent in the library logic, not OS-specific.

A DESCRIPTION OF THE PROBLEM :
Java’s 12-hour time formatting using DateTimeFormatter with the pattern hh:mm a produces ambiguous output for midnight (12:00 AM) and noon (12:00 PM).

This issue exists across all locales that default to 12-hour time. The time “12:00” is neither before nor after midday — making both “AM” and “PM” logically incorrect or at best unclear.

This affects applications that rely on localized time formatting for UI, logging, reporting, and more. When timestamps are shown in isolation (e.g., no surrounding context from other times), users often misinterpret the meaning of 12:00 AM vs 12:00 PM.

This issue is well-documented. For example, Wikipedia and the U.S. National Institute of Standards and Technology (NIST) both note that 12:00 AM and 12:00 PM are ambiguous and recommend explicitly using “12 noon” and “12 midnight” to avoid confusion.
1. Wikipedia – 12-hour clock
Link: https://en.wikipedia.org/wiki/12-hour_clock

2. NIST (National Institute of Standards and Technology) – FAQ on Time
Link: https://www.nist.gov/pml/time-and-frequency-division/popular-links/what-time-it

Most style guides, localization authorities, and even platforms like ICU4J offer better ways to present these times:

- Use explicit labels like “midnight” and “noon”

- Avoid showing ambiguous strings like "12:00 AM" or "12:00 PM" altogether

This is not a cosmetic detail — it's a practical usability and accessibility issue, especially in internationalized applications.

We propose that Java’s DateTimeFormatter should:

Support disambiguation for 12:00 AM / PM

Offer long-format or contextual rendering of midnight/noon

Optionally provide locale-specific 24-hour format defaults

Consider aligning with CLDR or ICU4J-style formatting options

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class TimeFormatTest {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US);

        System.out.println("Midnight: " + LocalTime.MIDNIGHT.format(formatter)); // 12:00 AM
        System.out.println("Noon: " + LocalTime.NOON.format(formatter));         // 12:00 PM
    }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When using 12-hour clock formatting (hh:mm a) in localized contexts, the output for 00:00 and 12:00 should be unambiguous and clearly distinguishable, especially in isolation.

Desirable behavior might include:

- Displaying "12:00 midnight" instead of "12:00 AM"

- Displaying "12:00 noon" instead of "12:00 PM"

- Providing a long-format or context-aware output option for disambiguation

- Locale-aware defaults that reduce confusion, especially in UIs or logs

Alternatively, developers should have a built-in way to opt into such disambiguation behavior via DateTimeFormatter, without requiring third-party libraries or custom post-processing.
ACTUAL -
When formatting midnight and noon using a 12-hour clock pattern (hh:mm a) with common locales such as Locale.US, Java outputs:

12:00 AM
12:00 PM

These outputs are:

Technically ambiguous (as 12:00 is neither ante meridiem nor post meridiem)

Easily misread by users as referring to the wrong time of day

Inconsistent with best practices for time clarity in internationalized applications

There is no standard, built-in way in the Java DateTimeFormatter API to disambiguate these times without resorting to 24-hour formatting or manual string replacement.

---------- BEGIN SOURCE ----------
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class TimeFormatTest {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.US);

        System.out.println("Midnight: " + LocalTime.MIDNIGHT.format(formatter)); // 12:00 AM
        System.out.println("Noon: " + LocalTime.NOON.format(formatter));         // 12:00 PM
    }
}

---------- END SOURCE ----------


Comments
CLDR's "day periods" has been supported since JDK16. Please use "B" format specifier to disambiguate such situations. e.g., ``` jshell> DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm B", Locale.US); formatter ==> Value(ClockHourOfAmPm,2)':'Value(MinuteOfHour,2)' 'DayPeriod(SHORT) jshell> System.out.println("Midnight: " + LocalTime.MIDNIGHT.format(formatter)); Midnight: 12:00 midnight jshell> System.out.println("Noon: " + LocalTime.NOON.format(formatter)); Noon: 12:00 noon ```
11-04-2025

java.time uses CLDR as the basis for formatting conventions and formats. The "a" formatting character is explicitly either AM or PM. The "B" formatting character provides day period notations like "noon", "midnight", "in the afternoon". Applications choose their output formats, whether strictly formatted or formatted for the particular locale. Changing the output of specific formatting characters such as "a" would likely break many applications and be incompatible.
11-04-2025

Moved to JDK as an enhancement for more discussions.
11-04-2025