我正在努力从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();

这会产生 LocalDate2005-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.timeOracle教程 和/或在网上搜索其他资源。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top