Pergunta

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.

Foi útil?

Solução

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).

Outras dicas

The Original Solution, doesn't work well always. My solution is easier and elegant:

Locale.US By default is 12 hours, then we set as 12 hours.

We check if the user has checked 24 hours format, then we set a Locale with 24 hours as default.

boolean twentyFourHourStyle = android.text.format.DateFormat.is24HourFormat(context);
DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US);
if (twentyFourHourStyle) {
    timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT,Locale.FRANCE);
}

Solved with 3 lines ;)

Make sure you use correct DateFormat class.

Use android.text.format.DateFormat.getTimeFormat(context);

This correctly updates, when you change the Time 12/24 format in Settings.

Do not use: java.text.DateFormat. This does not work.

e.g. Date date = new Date(); String time = android.text.format.DateFormat.getTimeFormat(context).format(date);

I realise this is an old problem but I'm here because DateFormat.getTimeInstance(DateFormat.SHORT) wasn't working for me either. It was fine with an API 26 (Android O) AVD but it wasn't working with my old API 16 and API 19 devices (Android 4). So it looks like the issue is just a bug with the older code. I'm now using android.text.format.DateFormat.getTimeFormat() combined with android.text.format.DateFormat.is24HourFormat() to get the correct time picker. That works on both my AVD and both my old devices.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top