Search code examples
androidsimpledateformatandroid-timepicker

12/24-hour mode conflict


I am a French Android developer, so using Locale.getDefault() causes my DateFormat to use a 24-hour mode. But, when I set manually my device to 12-hour mode via the setting menu, DateFormat keeps going in a 24-hour format.

On the contrary, TimePickers are set according to my own 12/24-hour setting.

Is there any way to make DateFormats behave the same way as TimePickers ?

EDIT:

Here is my DateFormat declaration:

timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault());

And here is where I set my TimePickerto 12 or 24-hour mode.

tp.setIs24HourView(android.text.format.DateFormat.is24HourFormat((Context) this));

My Solution:

According to @Meno Hochschild's answer below, here is how I solved this tricky problem:

boolean is24hour = android.text.format.DateFormat.is24HourFormat((Context) this);
tp.setIs24HourView(is24hour); // tp is the TimePicker
timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault());
if (timeFormat instanceof SimpleDateFormat) {
    String pattern = ((SimpleDateFormat) timeFormat).toPattern();
    if (is24hour) {
        timeFormat = new SimpleDateFormat(pattern.replace("h", "H").replace(" a",""), Locale.getDefault());
    }
    else {
        timeFormat = new SimpleDateFormat(pattern.replace("H", "h"), Locale.getDefault());
    }
}

After this, timeFormat will correctly format dates whether your device is set to display times in a 24-hour format or in a 12-hour one. And the TimePicker will be correctly set too.


Solution

  • If you have specified a pattern in SimpleDateFormat then you have fixed the 12/24-hour mode, either 12-hour-mode in case of pattern symbol "h" (1-12) or 24-hour-mode in case of pattern symbol "H" (0-23). The alternatives "k" and "K" are similar with slightly different ranges.

    That said, specifying a pattern makes your format independent from device setting!

    The alternative would be to use DateFormat.getDateTimeInstance() which makes the time style dependent on system locale (if Locale.getDefault() might change - or you have to deploy a mechanism how to ask the current device locale and then to set in Android-Java Locale.setDefault()).

    Another idea specific for Android is to ask directly the system settings using the string constant TIME_12_24 and then to specify a pattern dependent on this setting. This also seems to be possible by special method DateFormat.is24HourFormat() (note for your attention that Android has TWO different classes with name DateFormat). Concrete example for this approach:

    boolean twentyFourHourStyle = 
      android.text.format.DateFormat.is24HourFormat((Context) this);
    DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault());
    if (df instanceof SimpleDateFormat) {
      String pattern = ((SimpleDateFormat) df).toPattern();
      if (twentyFourHourStyle) {
        df = new SimpleDateFormat(pattern.replace("h", "H"), Locale.getDefault());
      } else {
        df = new SimpleDateFormat(pattern.replace("H", "h"), Locale.getDefault());
      }
    } else {
      // nothing to do or change
    }
    

    You are of course free to refine the code for possible occurrences of k and K or watch out for use of literals h and H (then parse for apostrophs to ignore such parts in replace-method).