18

当我在 中使用“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 开发人员似乎决定更改kDateFormat 函数的含义,它等同于 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. 

这是什么原因?

4

5 回答 5

9

我知道您已经接受了答案,但只是为了向您充分解释...

DateFormat.java 的源代码...

format此类中 的方法实现了 Unicode UTS #35模式的子集。此类当前支持的子集包括以下格式字符: acdEHhLKkLMmsyz. 直到 API 级别 17,仅adEhkMmszy受支持。请注意,此类错误地实现k,就好像它是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;
于 2013-05-26T22:54:50.883 回答
5

因为......这不是一回事,它的行为与文档所述相同?

来自android.text.format.DateFormat 的文档

此类仅支持完整 Unicode 规范的一个子集。如果您需要更多,请使用 SimpleDateFormat。

但是,如果您进一步阅读文档

公共静态最终字符 HOUR_OF_DAY

此指示符以 24 小时格式表示一天中的小时。下午 3 点的示例:k -> 15 午夜的示例:k -> 0 kk -> 00

所以......使用那个类,它会kk代替HH

于 2013-05-26T21:57:07.590 回答
3

kk对于 android.text.format.DateFormat,您可以像这样指定 Hour in day :

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 的文档:

公共静态最终字符 HOUR_OF_DAY

此指示符以 24 小时格式表示一天中的小时。下午 3 点的示例:k -> 15 午夜的示例:k -> 0 kk -> 00

于 2013-05-26T21:54:31.913 回答
1

我从来没有为 Android 编程过。我用谷歌搜索了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

于 2013-05-26T21:51:00.760 回答
1

这适用于所有 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);
        }
 }
于 2017-06-22T12:41:50.773 回答