tl;dr
For 12 AM.
LocalTime.MIN.with ( ChronoField.CLOCK_HOUR_OF_AMPM , 12 )
.with ( ChronoField.AMPM_OF_DAY , 0 );
For 12 PM.
LocalTime.MIN.with ( ChronoField.CLOCK_HOUR_OF_AMPM , 12 )
.with ( ChronoField.AMPM_OF_DAY , 1 );
Try it live.
Avoid legacy date-time classes
You are using troublesome old date-time classes that are now legacy, supplanted by java.time in Java 8 and later, and in Android supplanted by the adaptation of the java.time back-port.
LocalTime
Whenever possible, use 24-hour time as you mention in your Question. The LocalTime
class in java.time does this, using hours 0-23 for hour-of-day.
If forced to use 12-hour clock, one approach is to construct strings and then let LocalTime
parse them.
String input = hour + ":" + minute + " " + ( isAM ? "AM" : "PM" ) ; // Ex: 7:53 AM
DateTimeFormatter
Define a formatting pattern to match with DateTimeFormatter
class.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "h:m a" );
LocalTime lt = LocalTime.parse( input , f );
If all you need is time-of-day, you are done.
ZonedDateTime
If you need to associate this time with a date, create a LocalDate
object, specify the context of your intended time zone with a ZoneId
, and shake to mix into a ZonedDateTime
. If your time-of-day is invalid for that date, java.time makes an adjustment as needed. Be sure to study the JavaDoc to understand the behavior of such an adjustment to see if you agree.
LocalDate ld = LocalDate.of( 2017 , Month.MARCH , 4 );
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
TemporalField
The TemporalField
interface provides for classes that can alter date-time values. Because java.time uses immutable objects, we instantiate an fresh object based on another object but with a particular field altered. The ChronoField
enum provides some handy implementations of this interface.
The HOUR_OF_AMPM
object lets us specify the hour-of-day counting 1-12 rather than 0-23. Combine this with AMPM_OF_DAY
to specify if that 1-12 hour was meant for the morning (AM = 0) or the evening (PM = 1). You can chain these calls for convenience.
Let's try both AM and PM, passing either a zero or a one in that last argument. First AM, passing a 0
.
LocalTime fiveAm =
LocalTime.MIN.with ( ChronoField.HOUR_OF_AMPM , 5 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 0 ); // 05:23
And PM, passing a 1
.
LocalTime fivePm =
LocalTime.MIN.with ( ChronoField.HOUR_OF_AMPM , 5 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 1 ); // 17:23
Dump to console.
System.out.println ( "fiveAm.toString(): " + fiveAm );
System.out.println ( "fivePm.toString(): " + fivePm );
fiveAm.toString(): 05:23
fivePm.toString(): 17:23
That code above uses HOUR_OF_AMPM
which counts hours 0-11. Let's try a zero to see the effect.
LocalTime zeroAm =
LocalTime.MIN.with ( ChronoField.HOUR_OF_AMPM , 0 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 0 );
LocalTime zeroPm =
LocalTime.MIN.with ( ChronoField.HOUR_OF_AMPM , 0 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 1 );
Dump to console.
System.out.println ( "zeroAm.toString(): " + zeroAm );
System.out.println ( "zeroPm.toString(): " + zeroPm );
zeroAm.toString(): 00:23
zeroPm.toString(): 12:23
But the Question wants to use 12
, meaning we count hours of the 12-hour clock as 1-12 rather than 0-11. The java.time classes accommodate that as well. Just switch from using HOUR_OF_AMPM
to CLOCK_HOUR_OF_AMPM
.
LocalTime twelveAm =
LocalTime.MIN.with ( ChronoField.CLOCK_HOUR_OF_AMPM , 12 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 0 );
LocalTime twelvePm =
LocalTime.MIN.with ( ChronoField.CLOCK_HOUR_OF_AMPM , 12 )
.withMinute ( 23 )
.with ( ChronoField.AMPM_OF_DAY , 1 );
Dump to console.
System.out.println ( "twelveAm.toString(): " + twelveAm );
System.out.println ( "twelvePm.toString(): " + twelvePm );
twelveAm.toString(): 00:23
twelvePm.toString(): 12:23
Again, I advise you to use 24-hour clock whenever possible. Makes life much easier, works by default with LocalTime
class, and avoids the mistakes and confusion that comes from the ambiguity of 12-hour clock.
Live code
You can see all that example code running live at IdeOne.com.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.