Java SimpleDateFormat总是返回一月
-
01-10-2019 - |
题
我正在努力从Active Directory中获取日期值(CreateWhen),并将其转换为Java日期,以获取在两个日期之间创建的帐户列表。一切都很好,除了一种方法外,除了一个方法:从广告日期到Java日期的方法。该方法看起来像这样:
private Date getParsedDate(String givenString) {
System.out.println("Value from AD is: " + givenString);
Date parsedDate = null;
String formattedString = this.formatDateString(givenString);
System.out.println("Formatted String is: " + formattedString);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/DD");
try {
parsedDate = sdf.parse(formattedString);
System.out.println("Final date string is: " + parsedDate.toString());
} catch (ParseException ex) {
ex.printStackTrace();
}
return parsedDate;
}
并且,对于来自AD的一项任意数据:
Value from AD is: 20050912190509.0Z
Formatted String is: 2005/09/12
Final date string is: Wed Jan 12 00:00:00 EST 2005
显然,它可以正确地拾取日常和一年(如果我选择包括小时/分钟/秒,它也正确包含了这些),但是 每个日期 出于某种原因被安置在一月份。
现在,我敢肯定我的错误很简单,但是我已经重新检查了我的格式大约十次,而我正处于我再也看不到的。第二副眼睛能否希望看我的代码,并指出我要在哪里出错了这个月的严重不正确?
谢谢。
解决方案
将图案字符串从“ yyyy/mm/dd”更改为“ yyyy/mm/dd”
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
其他提示
确保你 别 使用“ MM”代替“ MM”或“ MMM”。小M表示分钟,帽子M表示一个月。
tl; dr
LocalDate parsedDate = OffsetDateTime
.parse("20050912190509.0Z", DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX"))
.toLocalDate();
这会产生 LocalDate
的 2005-09-12
.
Java.Time
我正在为现代答案做出贡献。 Suhas Phartale的答案 是正确的,是7年前写的一个很好的答案。现在臭名昭著的麻烦 SimpleDateFormat
课程已经过时了,我们的工作要好得多 java.time
, ,现代Java日期和时间API。我热情建议您使用此而不是旧的日期课程。
细节
从您的代码中,您可以从广告中重新格式化字符串。无需这样做,可以直接解析AD的字符串。我们可能将其直接解析为 LocalDate
, ,但我建议将其解析为 OffsetDateTime
抓住时间并偏移弦;如您所见,这可以直接转换为 LocalDate
然后。一种 LocalDate
是一天中没有时间的日期,因此它似乎比旧的更符合您的要求 Date
班级。
字符串在UTC中(由 Z
到底)。以上为您提供了字符串的日期,即UTC中的日期。相反,如果您想要日期,那是在9月12日19:05在UTC的当地时区:
LocalDate parsedDate = OffsetDateTime.parse(givenString, adDateTimeFormatter)
.atZoneSameInstant(ZoneId.of("America/Coral_Harbour"))
.toLocalDate();
我以为我们已将格式化器宣布为静态字段:
private static final DateTimeFormatter adDateTimeFormatter
= DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX");
在这种情况下,结果是相同的,而在其他时区则不会。请替换自己所需的时区为美国/coral_harbour。要使用JVM的时区设置,请指定 ZoneId.systemDefault()
. 。但是,请注意,可以通过程序的其他部分或在同一JVM中运行的其他程序更改设置,因此这很脆弱。
Suhas Phartale的回答的目的是有效的 java.time
同样:格式模式字符串对案例敏感,我需要使用小写 dd
每月。
教程
学习更多关于 java.time
在 Oracle教程 和/或在网上搜索其他资源。