将 SimpleDateFormat 转换为 DateTimeFormatter

Convert SimpleDateFormat to DateTimeFormatter

因此,当尝试使用 SimpleDateFormat 和 Date 替换一些遗留代码时,使用 java.time.DateTimeFormatter 和 LocalDate 我 运行 遇到了问题。这两种日期格式并不等同。在这一点上我必须说我知道这两个日期类型不一样但是我所处的场景意味着我从不关心时间方面所以可以忽略它。

public Date getDate(String value) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    try {
        return dateFormat.parse(value);
    } catch (ParseException e) {
        return null;
    }
}

public LocalDate getLocalDate(String value) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    try {
        return LocalDate.parse(value, formatter);
    } catch (DateTimeParseException e) {
        return null;
    }
}

public void testDates() {
    getDate("03/07/2016");               // Sun Jul 03 00:00:00 BST 2016
    getDate("3/7/2016");                 // Sun Jul 03 00:00:00 BST 2016
    getDate("3/7/2016 00:00:00");        // Sun Jul 03 00:00:00 BST 2016
    getDate("3/7/2016 00:00:00.0+0100"); // Sun Jul 03 00:00:00 BST 2016
    getDate("3/7/2016T00:00:00.0+0100"); // Sun Jul 03 00:00:00 BST 2016

    getLocalDate("03/07/2016");               // 2016-07-03
    getLocalDate("3/7/2016");                 // null
    getLocalDate("3/7/2016 00:00:00");        // null
    getLocalDate("3/7/2016 00:00:00.0+0100"); // null
    getLocalDate("3/7/2016T00:00:00.0+0100"); // null
}

如您所见,当在两个格式化程序中使用相同的模式时,DateTimeFormatter 最终会在您希望看到的日期与 SDF 的日期相同的地方产生空值。在这种情况下,我希望不需要的数据被删除,但事实并非如此。

那么,我们如何创建一个强大的 date/time 解析器?!

所以可能还有其他答案,但我想出的答案是针对我遇到的最极端的情况。首先,我将 dd/MM 减少为 d/M。这表示预期字符的最少数量,因此可以完全正确地解析两位数。请注意,您也可以使用 new DateTimeFormatterBuilder().parseLenient() 但这似乎没有必要。

其次,我决定在格式模式本身中使用可选子句。这允许您指定可能不提供哪些部分,这正是我试图解决的问题。

留给我们:

DateTimeFormatter.ofPattern("d/M/yyyy[' ']['T'][H:mm[:ss[.S]]][X]");

这将处理提供带或不带时间的日期,包括 T 分隔符、秒、毫秒和时区偏移。

运气好的话这对其他人有帮助!

private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy[' ']['T'][H:mm[:ss[.S]]][X]");

public LocalDate getRobustLocalDate(String value) {
    try {
        return LocalDate.parse(value, formatter);
    } catch (DateTimeParseException e) {
        return null;
    }
}

@Test
public void testDates() {
    getRobustLocalDate("03/07/2016");               // 2016-07-03
    getRobustLocalDate("3/7/2016");                 // 2016-07-03
    getRobustLocalDate("3/7/2016 00:00:00");        // 2016-07-03
    getRobustLocalDate("3/7/2016 00:00:00.0+0100"); // 2016-07-03
    getRobustLocalDate("3/7/2016T00:00:00.0+0100"); // 2016-07-03
}