android.text.format.DateFormat“HH”与java.text.SimpleDateFormat无法识别

当我在android.text.format.DateFormat使用“HH”标志时,它被解释为文字“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有bug吗?

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. 

这是什么原因?

  • Android格式带时区的date
  • Java / Android - 将GMT时间string转换为本地时间
  • SimpleDateFormat:不可parsing的dateexception
  • 在Android中获取日期对象的日期对象的价值?
  • SimpleDateFormat 24h
  • 将yyyy-mm-dd转换为dd mm yyyy
  • 我知道你已经接受了答案,但只是向你解释一下……

    从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; 

    因为…它不是同一件事,而且它的行为与文档说明的一样?

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

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

    但是如果你进一步阅读文档 :

    public static final char HOUR_OF_DAY

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

    所以…使用那个类,它是kk而不是HH

    对于android.text.format.DateFormat,你将每天的小时数指定为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

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

    使用与SimpleDateFormat相反的小写字母h标记“小时”,其中大写字母用于此目的。

    这适用于所有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); } }