Simpledateformat am/pm format returns "afternoon" instead of "PM"

Asked

Viewed 32 times

1

Using a solution to this question: https://stackoverflow.com/questions/6907968/how-to-convert-24-hr-format-time-in-to-12-hr-format

In doing the following:

        Int hour = 13;
        SimpleDateFormat _24HourSDF = new SimpleDateFormat("HH:mm");
        SimpleDateFormat _12HourSDF = new SimpleDateFormat("hh:mm a");
        Date _24HourDt = _24HourSDF.parse((Integer.toString(hour)+":00"));
        System.out.println(_24HourDt);
        System.out.println(_12HourSDF.format(_24HourDt));

The result of the second print is:

01:00 da tarde

How do I return:

01:00 PM
  • It’s probably the default locale of your JVM. Please see what is the result of System.out.println(Locale.getDefault()) (don’t forget to do the import java.util.Locale)

  • Returns: pt_PT How do I change?

1 answer

1


I could not reproduce (tested in Java 8 and 11, with different locales) but it’s probably because of default locale of the JVM (see which one is yours, with System.out.println(Locale.getDefault())).

What happens is that SimpleDateFormat uses the default locale of the JVM, and this locale can affect some formatting strings, as is the case of AM/PM.

For example, if I do:

// locale default será o do Japão
Locale.setDefault(new Locale("ja", "JP"));
int hour = 13;
SimpleDateFormat _24HourSDF = new SimpleDateFormat("HH:mm");
SimpleDateFormat _12HourSDF = new SimpleDateFormat("hh:mm a");
Date _24HourDt = _24HourSDF.parse((Integer.toString(hour) + ":00"));
System.out.println(_12HourSDF.format(_24HourDt));

The exit will be :

01:00 午後

For SimpleDateFormat uses the default locale which is configured at the moment it is instantiated. And this locale can affect strings that are used in formatting.

But if you want specific strings, which do not depend on what is configured in the JVM, then the solution is to set the locale in the creation of SimpleDateFormat:

SimpleDateFormat _12HourSDF = new SimpleDateFormat("hh:mm a", Locale.US);

In the case, Locale.US uses the locale corresponding to American English, which uses the strings "AM" and "PM".

This solution I find better because you only change what you need (the specific instance of SimpleDateFormat). If you change the default locale (with Locale.setDefault), this affects all applications that are running on the same JVM, and this may have unwanted side effects.


Java >= 8

From Java 8 you can use the API java.time, more modern and correcting various problems of Date and SimpleDateFormat (see more here).

For example, to create a time corresponding to 13:00, you don’t need all that "juggling" you’ve done with Date. Just create a java.time.LocalTime (a class that only has the time fields, which seems to be what you need):

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

...
// criar o horário 13:00
LocalTime time = LocalTime.of(13, 0);
// formatar (não esqueça do locale, para ter as strings AM/PM corretamente)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("hh:mm a", Locale.US);
System.out.println(fmt.format(time)); // 01:00 PM

To format, it is also necessary to set the locale, otherwise you end up having the same problem (he assumes the default of the JVM, and the strings "AM/PM" may not be exactly these).

  • 1

    It worked! Thank you very much. Good answer and explanation!

  • @lemario I don’t know which version of Java you’re using, but if it’s Java >= 8, there’s an alternative - in my opinion, much better - that’s using the API java.time. I added this option at the end of the reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.