a expects either PM or AM in upper case. To get a case insensitive formatter you need to build it manually:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern("EEE MMM dd, yyyy h:mma z")
        .toFormatter(Locale.US);

Note that you will get a new error because the 16th of July is not a Wednesday.

Answer from assylias on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java Platform SE 8 )
October 20, 2025 - Symbol Meaning Presentation Examples ... text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) number 0 k clock-hour-of-am-pm (1-24) number ...
🌐
How to do in Java
howtodoinjava.com › home › java date time › format timestamp in 12 hours pattern (am-pm) in java
Format Timestamp in 12 Hours Pattern (AM-PM) in Java
February 18, 2022 - Using the above information, we can create the following pattern to display time in 12-hour format including AM/PM information in formatted date string. ... Java program to display the current date-time in 12-hour format. We will create examples for LocalTime and LocalDateTime classes. For Date and Calendar classes, we can use SimpleDateFormat while for other classes we can use DateTimeFormatter.
🌐
BeginnersBook
beginnersbook.com › 2017 › 10 › java-display-time-in-12-hour-format-with-ampm
Java – Display time in 12 hour format with AM/PM using SimpleDateFormat
In this example we are displaying ... "+dateString); //Displaying current date and time in 12 hour format with AM/PM DateFormat dateFormat2 = new SimpleDateFormat("dd/MM/yyyy hh.mm aa"); String dateString2 = dateFormat2.format(new Date()).toString(); System.out.println("Current ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-program-to-format-time-in-am-pm-format
Java Program to Format Time in AM-PM format - GeeksforGeeks
July 23, 2025 - // Java program to convert 24 hour ... = new SimpleDateFormat("hh.mm aa"); // hh = hours in 12hr format // mm = minutes // aa = am/pm String time = formatTime.format( date); // changing the format of 'date' // display time as ...
🌐
Baeldung
baeldung.com › home › java › java dates › guide to datetimeformatter
Guide to DateTimeFormatter | Baeldung
March 26, 2025 - We can use DateTimeFormatter to uniformly format dates and times in an app with predefined or user-defined patterns. A quick and practical guide on transitioning to Java 8's new DateTime API.
🌐
Medium
medium.com › @smita.s.kothari › converting-a-12-hour-time-format-string-to-localdatetime-in-java-f9af73dc8c88
Converting a 12-Hour Time Format String to LocalDateTime in Java | by Smita Kothari | Medium
March 14, 2025 - The pattern for the given date-time ... month with 2 digits - hh: Hour in 12-hour format (01–12) - mm: Minutes (00–59) - a: AM/PM marker ......
🌐
Benchresources
benchresources.net › home › java › java 8 – how to get date/time with am/pm marker and zone ?
Java 8 – How to get Date/time with AM/PM marker and Zone ? - BenchResources.Net
August 29, 2022 - package in.bench.resources.jav... ZonedDateTime with Zone & AM/PM marker DateTimeFormatter dateTimeFormatter = DateTimeFormatter .ofPattern("dd-MMM-yyyy hh:mm:ss a z"); String formatterDateTime = dateTimeFormatter.format(zonedDateTime); System.out.print("\nFormatted Date/time ...
Find elsewhere
🌐
Netjstech
netjstech.com › 2017 › 10 › how-to-format-time-in-am-pm-format-java-program.html
How to Display Time in AM-PM Format in Java | Tech Tutorials
LocalTime t1 = LocalTime.of(5, 30, 56); DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss a"); String text = t1.format(df); System.out.println("Time - " + text); ... That's all for this topic How to Display Time in AM-PM Format in Java. If you have any doubt or any suggestions to ...
Top answer
1 of 3
4

You cannot parse the Strings due to two h in your format pattern instead of just one, and due to am-pm of day being in lower case letters. The a in the pattern String expects (standard/default) upper case, like AM.

You can either manipulate the Strings as shown in the other answer(s), but you can also use a DateTimeFormatter that can handle lower-case things. All you need is to build one with a DateTimeFormatterBuilder and make it parseCaseInsensitive() and apply a Locale:

public static void main(String[] args) {
    String dtStr = "1:23am-1:08am";
    String t1 = dtStr.split("-")[0];
    String t2 = dtStr.split("-")[1];
    // build a formatter that parses lower case am-pm of day
    DateTimeFormatter format = new DateTimeFormatterBuilder()
                                    .parseCaseInsensitive() // handles lower- and upper-case 
                                    .appendPattern("h:mma")
                                    .toFormatter(Locale.ENGLISH); // doesn't reliably work without a Locale
    LocalTime time1 = LocalTime.parse(t1, format);
    LocalTime time2 = LocalTime.parse(t2, format);
    Duration dur = Duration.between(time1, time2);
    System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");
}

Output:

-15 minutes 0 seconds

This is a little more flexible than manipulating the input before parsing, because this one can also parse upper-case am-pm of day.

2 of 3
3

You need to use the following pattern h:mma because of one-digit hour, also a parses AM/PM in uppercase

String dtStr = "1:23am-1:08am";
String t1 = dtStr.split("-")[0].toUpperCase();
String t2 = dtStr.split("-")[1].toUpperCase();
DateTimeFormatter format = DateTimeFormatter.ofPattern("h:mma");

LocalTime time1 = LocalTime.parse(t1, format);
LocalTime time2 = LocalTime.parse(t2, format);
Duration dur = Duration.between(time1, time2);
System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");
-15 minutes 0 seconds

java.time format specifications

🌐
TutorialsPoint
tutorialspoint.com › java-program-to-format-time-in-am-pm-format
Java Program to Format time in AM-PM format
To format time in AM-PM format, we can use the following approaches ? ... In Java, the SimpleDateFormat class is a subclass of DateFormat class. It provides multiple methods to parse and format date/time.
Top answer
1 of 2
8
What is the locale on each machine? Is it the same version of Java on both?
2 of 2
1
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
🌐
OpenJDK
cr.openjdk.org › ~rriggs › threeten › javadoc-raw-types-163 › java › time › format › DateTimeFormatter.html
DateTimeFormatter (ThreeTen Date and Time API)
Symbol Meaning Presentation Examples ------ ------- ------------ ------- G era text AD; Anno Domini; A u year year 2004; 04 y year-of-era year 2004; 04 D day-of-year number 189 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10 Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter Y week-based-year year 1996; 96 w week-of-year number 27 W week-of-month number 27 E day-of-week text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) numb
🌐
CodingTechRoom
codingtechroom.com › question › java-8-datetimeformatter-am-pm-formatting
How to Use Java 8 DateTimeFormatter for AM/PM Formatting - CodingTechRoom
Use a pattern string like "hh:mm a" for 12-hour format with AM/PM indicators. Consider using LocalTime or LocalDateTime for time manipulation. To handle different time zones, use ZonedDateTime. Mistake: Using 24-hour format pattern with AM/PM.
Top answer
1 of 3
3

Use proper date-time objects for your dates and times

For the vast majority of purposes you should not keep your date and time in a string and should not convert your date and time from a string in one format to a string in another format. Keep your date and time in a ZonedDateTime or LocalDateTime object.

When you are required to accept string input, parse that input into a date-time object immediately. I am using and recommending java.time, the modern Java date and time API:

    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
    String input = "11/06/2020 04:14:20";
    LocalDateTime dateTime = LocalDateTime.parse(input, inputFormatter);
    System.out.println(dateTime);

Output so far is:

2020-06-11T04:14:20

Since there is no AM or PM in your string, I have assumed that 04:14:20 was the time of day from 00:00:00 through 23:59:59. If you intended otherwise, you need to explain how.

Only when you need to give string output, format your date and time back into a string of appropriate format:

    DateTimeFormatter outputFormatter = DateTimeFormatter
            .ofPattern("MMMM dd, yyyy hh:mm:ss a", Locale.ENGLISH);
    String output = dateTime.format(outputFormatter);
    System.out.println(output);

June 11, 2020 04:14:20 AM

Do provide a locale for the formatter so Java knows which language to use for the month name and the AM/PM indicator.

What went wrong in your code?

Your string has no AM nor PM: 11/06/2020 04:14:20. Yet your format pattern string requires an AM/PM marker in the end. This is what format pattern letter a signifies. So your string wasn’t in the format that you required. This was the reason for the exception that you observed.

Link

Oracle tutorial: Date Time explaining how to use java.time.

2 of 3
2

You can check this code you have to pass the am/pm part too with the date string value as your format is expecting that.

//String date = "11/06/2020 04:14:20";
String date = "11/06/2020 04:14:20 am";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");

https://ideone.com/3nibwJ

🌐
Oracle Communities
community.oracle.com › thread › 4077857
DateTimeFormatter am/pm java 9 case changed | Oracle Community
String formattedDate = DateTimeFormatter.ofPattern("a").format(LocalDateTime.now()); System.out.println(formattedDate); assertThat(formattedDate).isEqualTo("PM"); ... I am getting the same output in JDK 8u144 as well as 9-ea+181, here is the output on running the code provided by you:
🌐
Oracle
docs.oracle.com › javase › 10 › docs › api › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java SE 10 & JDK 10 )
As this formatter has an optional element, it may be necessary to parse using parseBest(java.lang.CharSequence, java.time.temporal.TemporalQuery<?>...). The returned formatter has a chronology of ISO set to ensure dates in other calendar systems are correctly converted. It has no override zone and uses the STRICT resolver style. public static final DateTimeFormatter ISO_LOCAL_TIME
Top answer
1 of 2
3
  1. Since hour within AM or PM can be 1 digit, specify so. Use the overloaded appendValue method that accepts a minimum and a maximum field width.
  2. As Edwin Daloezo already said, you probably want ChronoField.CLOCK_HOUR_OF_AMPM.
  3. You need am or pm unconditionally, so it should be outside of optionalStart()optionalEnd() as Turing85 said in a comment.
  4. Consider whether you need to accept am or AM or both. In that last case you need to specify case insensitive parsing.
  5. Always specify a locale (a language) for your formatters. While AM and PM are hardly used in other langauges than English, they do have different values (texts) in other languages.

So my go is:

    String time = "2:00 am";

    DateTimeFormatter format = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.CLOCK_HOUR_OF_AMPM, 1, 2, SignStyle.NEVER)
            .appendLiteral(':')
            .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
            .optionalEnd()
            .appendLiteral(' ')
            .appendText(ChronoField.AMPM_OF_DAY)
            .toFormatter(Locale.forLanguageTag("en-AU"));

    System.out.println(LocalTime.parse(time, format));

Output is:

02:00

In Australian English am and pm are in lower case (according to my Java 11), so I specified this locale. Which you should only do if your input comes from Australia, or it will just confuse (there are a few more locales where am and pm are in lower case). To accept lower case am and pm from another English-speaking locale, use parseCaseInsensitive(). For example:

    DateTimeFormatter format = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.CLOCK_HOUR_OF_AMPM, 1, 2, SignStyle.NEVER)
            .appendLiteral(':')
            .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
            .optionalEnd()
            .appendLiteral(' ')
            .parseCaseInsensitive() // Accept AM or am
            .appendText(ChronoField.AMPM_OF_DAY)
            .toFormatter(Locale.ENGLISH);

If you want a format pattern string

This is no recommendation per se. If you do not need case insensitive parsing, it is possible to build your formatter from a format pattern string rather than a builder. On one hand it may be even more error-prone, on the other it’s much shorter.

    DateTimeFormatter format = DateTimeFormatter
            .ofPattern("h:mm[.ss] a", Locale.forLanguageTag("en-AU"));

Output is the same as before. The square brackets in the format pattern string specify that the seconds are optional.

If you do need case insensitive parsing, you do need the builder for specifying it.

You may also mix the approaches since a builder too accepts a format pattern string:

    DateTimeFormatter format = new DateTimeFormatterBuilder()
            .parseCaseInsensitive() // Accept AM or am
            .appendPattern("h:mm[.ss] a")
            .toFormatter(Locale.ENGLISH);
2 of 2
0

I believe you need to change HOUR_OF_DAY which goes from (0-23) to CLOCK_HOUR_OF_AMPM which goes from (1-12). I also added a space literal before AM/PM and used appendText instead of appendValue for the AM/PM field.

The following works just fine.

var formatter = new DateTimeFormatterBuilder()
                .appendValue(CLOCK_HOUR_OF_AMPM, 2)
                .appendLiteral(':')
                .appendValue(MINUTE_OF_HOUR, 2)
                .optionalStart()
                .appendLiteral(":")
                .appendValue(SECOND_OF_MINUTE, 2)
                .optionalStart()
                .appendLiteral(" ")
                .appendText(AMPM_OF_DAY)
                .toFormatter();

        //formatter = new DateTimeFormatterBuilder().appendPattern("hh:mm:ss a").toFormatter();
var time = LocalTime.parse("07:20:54 AM", formatted);
System.out.println(time);  // 19:20:54
🌐
Zapier
community.zapier.com › how-do-i-3 › how-do-i-use-the-time-formatter-to-get-12-hour-time-am-pm-from-24-hour-time-20676
How do I use the time formatter to get 12 hour time (AM / PM) from 24 hour time | Zapier Community
January 18, 2023 - Is there anything I can do with the Date/Time formatter to get YYYY MM DD HHA:mm (12 hour am pm time) from YYYY-MM-DDTHH:mm:ssZ (24 hour time from Outlook) ?*edit* time format above should be YYYY - MM - DD T HH : mm : ssZ (added spaces to avoid emoji above)This article mentions that I can input an...