51

Do i need to be worried about this warning? What if I ignore the warning?
What does this warning mean:
To get local formatting use getDateInstance(), getDateTimeInstance(), or getTimeInstance(), or use new SimpleDateFormat(String template, Locale locale) with for example Locale.US for ASCII dates.
In the 2nd Line of the code below. The App is working fine with the code. I wanted to show date eg, 19 Nov 2014.

public static String getFormattedDate(long calendarTimeInMilliseconds) {
    SimpleDateFormat sdfDate = new SimpleDateFormat("d MMM yyyy");  //ON THIS LINE
    Date now = new Date();
    now.setTime(calendarTimeInMilliseconds);
    String strDate = sdfDate.format(now);
    return strDate;
}

I think this is a correct way to format date as shown here.

Community
  • 1
  • 1
Mohammed Ali
  • 2,758
  • 5
  • 23
  • 41

4 Answers4

87

You are currently using the SimpleDateFormat(String) constructor. This implies the default locale and as the Locale documentation tells you, be wary of the default locale as unexpected output can be produced on various systems.

You should instead use the SimpleDateFormat(String, Locale) constructor. It is going to take in an additional parameter - the locale you want to use. If you want to make sure the output is machine-readable in a consistent way (always looks the same, regardless of the actual locale of the user), you can pick Locale.US. If you do not care about machine redability, you can explicitly set it to use Locale.getDefault().

Using those on your example code would look something like this:

// for US
SimpleDateFormat sdfDate = new SimpleDateFormat("d MMM yyyy", Locale.US);

// or for default
SimpleDateFormat sdfDate = new SimpleDateFormat("d MMM yyyy",
        Locale.getDefault());
Valter Jansons
  • 3,904
  • 1
  • 22
  • 25
  • SimpleDateFormat sdfDate = new SimpleDateFormat("d MMM yyyy", Locale.getDefault()); Will this format the date as 19 Nov 2014 or "d MMM yyyy" even in different language? – Mohammed Ali Nov 19 '14 at 17:54
  • 1
    The template is still going to stay `d MMM yyyy` which stands for "day in month", "month in year", "year" as can be seen in [SimpleDateFormat](http://developer.android.com/reference/java/text/SimpleDateFormat.html) docs, but the best way to make sure is to actually test yourself by switching over your device/emulator to a custom locale as that will show you how it will work in real life. – Valter Jansons Nov 19 '14 at 18:01
  • Locale.getDefault(). So, the default locale is appropriate for tasks that involve presenting data to the user. In this case, you want to use the user's date/time formats, number formats, rules for conversion to lowercase, and so on. In this case, it's safe to use the convenience methods. – Mohammed Ali Nov 19 '14 at 18:02
  • Yes, the convenience methods that the warning mentions are great to use when all you want is to display the datetime simply to the user. I provided my answer under the assumption that you want to retain the specific ordering for everyone - if that is not a requirement, you probably want to use a plain [getDateInstance()](http://developer.android.com/reference/java/text/DateFormat.html#getDateInstance()). – Valter Jansons Nov 19 '14 at 18:07
  • Additionally, Locale.US is the preferred standard locale to use when enforcing a single locale for all users as it is the one locale that is guaranteed to always be available to use (see [Available locales](http://developer.android.com/reference/java/util/Locale.html#available_locales) docs section) and it functions in a manner that is familiar to programmers, especially since a large chunk of programmers use en_US as their locale of choice for daily use on their devices. – Valter Jansons Nov 19 '14 at 18:12
  • yes I want to retain the order `d MMM yyyy` . So, Locale.getDefault() will be useful? even in different language. Nice ans by the way.. – Mohammed Ali Nov 19 '14 at 18:14
  • `Locale.getDefault()` should act as your existing code already does. It just implies that you do want the default locale to be used. I would suggest you to add that to the codebase, rebuild, reinstall and try the new codebase out using other locales (languages) on the device just to confirm it works how you expect it to work. – Valter Jansons Nov 19 '14 at 18:17
6

You can ignore it, but the warning is there to let you know the dates may display unexpectedly for users using a different language. If you want to force the format in your own locale, use Locale.US (or whichever locale matches your format requirements). Otherwise use one of the getInstance() methods for localized formatting.

JstnPwll
  • 8,585
  • 2
  • 33
  • 56
3

Same for kotlin

        //example long 1372339860 
        fun getDateTime(unixSeconds: Long): String {
         val date = java.util.Date(unixSeconds * 1000L)

         val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.getDefault())
         return simpleDateFormat.format(date)
        }

Call like this getDateTime(1372339860)

It will return 27.6.2013 15:31:00 GMT +2 The GMT+2 because I'm in Germany and we have summer time. You can use Locale.US as well.

kuzdu
  • 7,124
  • 1
  • 51
  • 69
0

We can get rid of that by using the following code:

val dateFormat = SimpleDateFormat("d MMM yyyy", Locale("IN"))

Although we have other solutions mentioned here, I wasn't getting Indian locale from here. After some researching, I figured out this solution.
You can find strings (for your country) to pass in Locale constructor from here, under Type: region

Mr. Techie
  • 622
  • 7
  • 17