0

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”

user20191130
  • 340
  • 1
  • 9

2 Answers2

2

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.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

I had solved it in a different way. Maybe, it helps you. But unfortunately, I couldn't try the code on Android...

Here is my code:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

// other code...

int numberOfHourFrom_0_to_23 = 15;
String hour = numberOfHourFrom_0_to_23 + ""; // you need a string for the following parsing
                
String mstring = ""; 
// you have to do it here, because in the other case you do it in the try block, 
// you wouldn't have access on it after finishing it
try{
    DateFormat hh = new SimpleDateFormat("hh"); 
    // your input date format, in this case only hours
    Date date = hh.parse(hour); 
    /* you have to parse the value of the string to a Date object, 
    can throw a 'ParseException' exception --> try-catch */
            
    SimpleDateFormat targetFromat = new SimpleDateFormat("hh aa"); 
    // your target format, 'aa' is for AM/PM
            
    mstring = targetFromat.format(date);
    // the method formats the time to the new format (incl. AM/PM)
} catch(ParseException e){
    // exception threw by parse in the class Date
    System.err.println("There was an error during parsing the initial string.");
    e.printStackTrace();
}
        
System.out.println(mstring); // test output, in this case: 03 PM

Maybe is this article interesting for you: https://beginnersbook.com/2017/10/java-display-time-in-12-hour-format-with-ampm/ (it helped me by this answer).

UPDATE: After reading the comment from @Ole V.V. (thank you for your correction!), I look at the class DateTimeFormatter and I want to add the code here (it is much simpler as my first code!):

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

// other code...

int numberOfHourFrom_0_to_23 = 15; 

LocalTime time = LocalTime.of(numberOfHourFrom_0_to_23, 0, 0);
// parameters: hour, minute, second

String formatPattern = "hh a";
// the pattern, "hh" is for the two hours positions and "a" for AM/PM

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern);
String mstring = formatter.format(time);
// formatting the value and solve it as a String

System.out.println(mstring); // test output, in this case: 03 PM
bef
  • 36
  • 4
  • Thanks for wanting to contribute. Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. We have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Yes, you can use it on Android. For older Android look into [desugaring](https://developer.android.com/studio/write/java8-support-table). – Ole V.V. Feb 19 '21 at 16:30
  • 1
    @OleV.V., thank you for the feedback! I have updated my answer. – bef Feb 19 '21 at 17:01