Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android.text.format.DateFormat "HH" is not recognized like with java.text.SimpleDateFormat

When I use the "HH" flag in android.text.format.DateFormat, it is interpreted as a literal "HH". But when I use java.text.SimpleDateFormat it is interpreted as the 2 digit Hour. Why are they different?

I'm not looking for a working alternative (I already know I have to use kk instead of HH). I'm just curious why "HH" isn't recognized.

Java example:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Calendar calendar = Calendar.getInstance();

    String dateJava = new java.text.SimpleDateFormat(
        "dd-MM-yyyy HH:mm:ss").format(calendar.getTime());

    String dateAndroid = android.text.format.DateFormat.format(
        "dd-MM-yyyy HH:mm:ss", calendar).toString();

    TextView tvAndroid = (TextView) findViewById(R.id.tvAndroid);
    TextView tvJava = (TextView) findViewById(R.id.tvJava);

    tvAndroid.setText("Android: " + dateAndroid);  //prints 26-05-2013 HH:36:34
    tvJava.setText("Java: " + dateJava);           //prints 26-05-2013 22:36:34
}

Output is:

Android: 26-05-2013 HH:36:34 
Java:    26-05-2013 22:36:34

I expect both to be 26-05-2013 22:36:34

Does Android's DateFormat have a bug?

Java's SimpleDateFormat accepts these:

H   Hour in day (0-23)      Number  0
k   Hour in day (1-24)      Number  24
K   Hour in am/pm (0-11)    Number  0
h   Hour in am/pm (1-12)    Number  12

So it appears the Android developers decided to change the meaning of k and in their DateFormat function it is equivalent to the SimpleDateFormat H as they explicitly say in their documentation page:

This constant was deprecated in API level 18. Use a literal 'H' (for 
compatibility with SimpleDateFormat and Unicode) or 'k' (for compatibility 
with Android releases up to and including Jelly Bean MR-1) instead. Note 
that the two are incompatible. 

What is the reason for this?

like image 365
Alejandro Colorado Avatar asked May 26 '13 21:05

Alejandro Colorado


People also ask

How to get time format in Android?

For example to display the current date and time do the following: Date date = new Date(location. getTime()); DateFormat dateFormat = android. text.

What is the difference between DateFormat and SimpleDateFormat?

SimpleDateFormat is very much like DateFormat, the only major difference between them is that SimpleDateFormat can be used for formatting (Date to String conversion) and for parsing (String to Date conversion) with locale support, whereas DateFormat don't have locale support.

How to format the Datetime in Java?

String pattern = "MM-dd-yyyy"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); In the example above the String pattern is the pattern which will be used to format a date and the output will be generated in that pattern as “MM-dd-yyyy”.


1 Answers

I understand you have accepted an answer already but just to explain this fully to you...

From the source code for DateFormat.java...

The format methods in this class implement a subset of Unicode UTS #35 patterns. The subset currently supported by this class includes the following format characters: acdEHhLKkLMmsyz. Up to API level 17, only adEhkMmszy were supported. Note that this class incorrectly implements k as if it were H for backwards compatibility.

Note the part I have marked in bold.

The source I linked to has been updated to allow the use of H but it isn't on general release yet (API 17 is the current release of Android and doesn't support H).

Later in the source, at the stage of declaring the format character constants, there is this comment...

/**
 * @deprecated Use a literal {@code 'H'} (for compatibility with {@link SimpleDateFormat}
 * and Unicode) or {@code 'k'} (for compatibility with Android releases up to and including
 * Jelly Bean MR-1) instead. Note that the two are incompatible.
 */
@Deprecated
public  static final char    HOUR_OF_DAY            =    'k';

...and later during character replacement...

case 'H': // hour in day (0-23)
case 'k': // hour in day (1-24) [but see note below]
{
    int hour = inDate.get(Calendar.HOUR_OF_DAY);
    // Historically on Android 'k' was interpreted as 'H', which wasn't
    // implemented, so pretty much all callers that want to format 24-hour
    // times are abusing 'k'. http://b/8359981.
    if (false && c == 'k' && hour == 0) {
        hour = 24;
    }
    replacement = zeroPad(hour, count);
}
break;
like image 59
Squonk Avatar answered Oct 02 '22 00:10

Squonk