javaandroidcalendargregorian-calendar

Calendar: how to get string “10:00 AM”


I’m trying to get a string like e.g. “10:00 AM”

int numberOfHourFrom_0_to_23=10;
Calendar m_auxCalendar = new GregorianCalendar();
m_auxCalendar.set(Calendar.HOUR, numberOfHourFrom_0_to_23 +12);//+12 makes it work correctly during PM hours, but not sure why.
m_auxCalendar.set(Calendar.MINUTE,0);

Date mdate=m_auxCalendar.getTime();
String mstring  = DateFormat.getTimeInstance(DateFormat.SHORT).format(mdate);

If I use my Android phone during PM hours, this code works correctly (I get “10:00 AM”); however, if I use my phone during AM hours, I get “10:00 PM” instead of “10:00 AM”


Solution

  • java.time through desugaring

    Consider using java.time, the modern Java date and time API, for your time work.

        DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
        
        int numberOfHourFrom0To23 = 10;
        LocalTime time = LocalTime.of(numberOfHourFrom0To23, 0);
        String mstring = time.format(timeFormatter);
        
        System.out.println(mstring);
    

    Output in US locale is (no surprises):

    10:00 AM

    A LocalTime is a time of day with no date, so seems to be all that you need here.

    What went wrong in your code?

    Unexpectedly Calendar.HOUR refers to hour within AM or PM, from 0 through 11. I never understood for what this is useful. When you create a GregorianCalendar in the morning and set its HOUR to 10, you get 10 AM. When you do the same in the afternoon, you get 10 PM. You tried to compensate by adding 12 hours. Now you set the hour to 22 even though the range was o through 11. Any decent class would throw an IllegalArgumentException (or similar). Not a Calendar object with default settings. Instead it adjusts the time to 10 AM on the next day. And now when you run your code in the morning, you get 10 PM, as you observed.

    Question: Doesn’t java.time require Android API level 26?

    java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

    Links