这是我的原始代码 -
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
oldDate
和newDate
之间存在 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小时格式,而hh
表示 12小时格式。
我的问题是
如果我使用HH:mm a
代替hh:mm a
,那么这不应该以 24小时格式返回时间吗?
(或)
如果默认为 12小时格式,根据提供的日期输入,是否应该返回相应的AM / PM标记?
这只是为了我的理解。
答案 0 :(得分:9)
更新了答案
问题在于Program flow
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a");
此simple date formatter
用于格式化日期对象的日期字符串,这是答案的重要部分
当您使用 HH 而不是 hh 时, SimpleDateFormater 会认为提供的日期字符串位于24-Hour Format
并且只是< strong>忽略 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
不是en_us
。
IMP :代码也在 Java 8 上进行了测试。 Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
答案 1 :(得分:6)
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.
hh:mm a或HH中的a
:mm a是Am / pm标记,有关详细信息,请转到link
答案 2 :(得分:1)
简单的测试是解释模式“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:m a", 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:m a", 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.US
或new Locale("en", "US")
代替new Locale("en-US")
,因为语言“en-US”不存在。