hh:mm a和HH之间的差异:mm a

这是我原来的代码 –

String dateString = "23 Dec 2015 1:4 PM"; Locale locale = new Locale("en_US"); SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale); Date date = null; try { date = formatter.parse(dateString); } catch (ParseException e) { LOGGER.error(e); } String newDate = df.format(date); System.out.println("oldDate = " + dateString); System.out.println("newDate = " + newDate); 

这是我的输出 –

 oldDate = 23 Dec 2015 1:4 PM newDate = 23 Dec 2015 01:04 AM 

oldDatenewDate之间存在AM-PM差异 。 现在我将DateFormat代码更改为 –

 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a"); DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm a", locale); 

我得到了预期的输出,这是 –

 oldDate = 23 Dec 2015 1:4 PM newDate = 23 Dec 2015 01:04 PM 

我知道HH表示24小时格式,而且表示12小时格式。

我的问题是

如果我使用HH:mm a而不是hh:mm a ,那么这不应该以24小时格式返回时间吗?

(要么)

如果它默认为12小时格式,根据提供的日期输入,是否应该返回相应的AM / PM标记?

这只是为了我的理解。

更新的答案

这里的问题在于Program flow

 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); 

这个simple date formatter用于格式化Date对象的日期字符串,这是答案的重要部分

当您使用HH而不是hh时SimpleDateFormater认为提供的日期字符串是24-Hour Format并且在此处忽略 AM/PM marker

从这个SimpleDateFormatter构造的Date对象被传递给

 DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale); 

这就是它打印的原因

 newDate = 23 Dec 2015 01:04 AM 

如果你改变了这条线

 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); 

 SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a"); 

一切都会顺利进行!

注意 :创建语言环境时,应将语言代码传递给Locale()构造函数。 en-us not en_us

IMP :Code也在Java 8上进行了测试。 Java(TM) SE Runtime Environment (build 1.8.0_121-b13)

hh:mm和HH之间的差异:mm:

  HH:mm => will look like 00:12, 23:00... this has 24 hour format. hh:mm => will look like 01:00Am, 02:00Am,...01:00pm this has 12 hour format. 

a hh:mm a或HH:mm a是Am / pm标记,有关详细信息,请转到链接

一个简单的测试是解释模式“HH:mm a”的最佳答案。 首先让我们研究一下打印模式

旧格式引擎SimpleDateFormat

 Calendar cal = new GregorianCalendar(2015, 3, 1, 17, 45); SimpleDateFormat sf = new SimpleDateFormat("HH:mm a", Locale.US); System.out.println(sf.format(cal.getTime())); // 17:45 PM 

Java-8(使用新包java.time.format ):

 LocalTime time = LocalTime.of(17, 59); DateTimeFormatter tf = DateTimeFormatter.ofPattern("HH:mm a", Locale.US); System.out.println(tf.format(time)); // 17:59 PM 

在这两种情况下, 我们都没有观察到任何覆盖 。 我更喜欢这种方法,因为在我看来使用“HH”和“a”的组合反而是编程错误的指示(用户显然没有充分考虑这些模式符号的含义和官方描述)。

现在让我们研究解析模式 (我们将使用严格模式来观察场景背后的真实情况):

 String dateString = "23 Dec 2015 1:4 PM"; SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy H:ma", Locale.US); df.setLenient(false); Date date = df.parse(dateString); // java.text.ParseException: Unparseable date: "23 Dec 2015 1:4 PM" 

Java-8中的行为如何? 它是相同的,但有一个更清晰的错误信息:

 DateTimeFormatter tf = DateTimeFormatter.ofPattern("H:ma", Locale.US); tf = tf.withResolverStyle(ResolverStyle.STRICT); LocalTime.parse("1:4 PM", tf); // DateTimeException: Cross check failed: AmPmOfDay 0 vs AmPmOfDay 1 

此消息告诉我们,具有值“1”的解析小时(以24小时格式!)表示AM,而文本输入包含另一个解析的AM / PM值“PM”。 这种矛盾心理无法解决。

经验教训:我们必须小心宽松的解析,其中矛盾的信息可以被忽略并导致错误的假设。 @Arjun接受的答案是完全错误的。

顺便说一句:请使用Locale.USnew Locale("en", "US")而不是new Locale("en-US")因为语言“en-US”不存在。