Подтвердить что ты не робот

Android.text.format.DateFormat "HH" не распознается как с java.text.SimpleDateFormat

Когда я использую флаг "HH" в android.text.format.DateFormat, он интерпретируется как буква "HH" . Но когда я использую java.text.SimpleDateFormat, это интерпретируется как 2-значный Час. Почему они разные?

Я не ищу рабочую альтернативу (я уже знаю, что мне нужно использовать kk вместо HH). Мне просто интересно, почему "HH" не распознается.

Пример Java:

@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
}

Выход:

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

Я ожидаю, что оба будут 26-05-2013 22:36:34

Есть ли у Android DateFormat ошибка?

Java SimpleDateFormat принимает следующие значения:

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

Итак, разработчики Android решили изменить значение k, а в их функции DateFormat он эквивалентен SimpleDateFormat H, как они явно указывают на странице документации :

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. 

В чем причина этого?

4b9b3361

Ответ 1

Я понимаю, что вы уже приняли ответ, но просто для того, чтобы полностью объяснить это вам...

Из исходного кода для DateFormat.java...

Методы {@code format} в этом классе реализуют подмножество Unicode UTS № 35. Подмножество, поддерживаемое этим классом, включает следующие символы формата: {@code acdEHhLKkLMmsyz}. До уровня API до уровня 17 поддерживались только {@code adEhkMmszy}. Обратите внимание, что этот класс неправильно реализует {@code k}, как если бы он {@code H} для назад совместимость.

Обратите внимание на часть, выделенную жирным шрифтом.

Источник, с которым я связан, был обновлен, чтобы разрешить использование H, но он еще не находится в общем выпуске (API 17 - это текущая версия Android и не поддерживает H).

Позже в источнике, на этапе объявления символьных констант формата, есть этот комментарий...

/**
 * @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';

... и позже при замене символов...

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;

Ответ 2

Потому что... это не одно и то же, и он ведет себя так, как заявляет документация?

Из Документация для android.text.format.DateFormat

Этот класс поддерживает только подмножество полной спецификации Юникода. Используйте SimpleDateFormat, если вам нужно больше.

Но если вы читаете дальнейшие документы:

public static final char HOUR_OF_DAY

Этот указатель указывает час дня в 24-часовом формате. Пример для 3 вечера: k → 15 Примеры для полночи: k → 0 kk → 00

Итак... используя этот класс, это будет kk вместо HH

Ответ 3

Для android.text.format.DateFormat вы назначаете Hour in day как kk следующим образом:

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

Для java.text.SimpleDateFormat вы назначаете час в день как HH.

H час в день (0-23)

Документация для android.text.format.DateFormat:

public static final char HOUR_OF_DAY

Этот указатель указывает час дня в 24-часовом формате. Пример для 3 вечера: k → 15 Примеры для полночи: k → 0 kk → 00

Ответ 4

Я никогда не программировал для Android. Я googled DateFormat javadoc и увидел там следующие примеры:

Examples for April 6, 1970 at 3:23am:
"MM/dd/yy h:mmaa" -> "04/06/70 3:23am"
"MMM dd, yyyy h:mmaa" -> "Apr 6, 1970 3:23am"
"MMMM dd, yyyy h:mmaa" -> "April 6, 1970 3:23am"
"E, MMMM dd, yyyy h:mmaa" -> "Mon, April 6, 1970 3:23am&
"EEEE, MMMM dd, yyyy h:mmaa" -> "Monday, April 6, 1970 3:23am"
"'Noteworthy day: 'M/d/yy" -> "Noteworthy day: 4/6/70"

"Час" отмечен маленькой буквой h в противоположность SimpleDateFormat, где для этой цели используется заглавная буква.

Ответ 5

Эта работа для всех Android 4.0+ и для двух форматов даты.

Использовать java.text.SimpleDateFormat.

Пример работы:

24-часовой формат использует этот шаблон даты = " dd-MM-yyyy HH: mm";

12-часовой формат использует этот шаблон даты = " dd-MM-yyyy hh: mm a";

public static String getDateAsString(Date date, String pattern) {
        Locale locale = new Locale("EN");
        SimpleDateFormat sdf = null;
        try {
            sdf = new SimpleDateFormat(pattern, locale);
            return sdf.format(date);
        } catch (IllegalArgumentException ex) {
            // default format
            sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm", locale);
            return sdf.format(date);
        }
 }