Convert SimpleDateFormat to DateTimeFormatter

旧城冷巷雨未停 提交于 2020-01-12 13:52:06

问题


So when trying to replace some legacy code using SimpleDateFormat and Date, to use java.time.DateTimeFormatter and LocalDate I ran into a problem. The two date formats are not equivalent. At this point I must say I know the two date types are not the same but the scenario I am in means I never care about the time aspect so can ignore it.

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
}

As you can see when the same pattern is used in both formatters the DateTimeFormatter ends up producing nulls where you'd expect to see dates equivalent to that of SDF. In this scenario I would expect the unrequired data to be dropped but it isn't.

So, how do we create a robust date/time parser?!


回答1:


So there may be other answers to this but what I came up caters for the most extreme case I have. Firstly I reduced dd/MM to d/M. This denotes the minimum number of expected characters so will parse double digits completely fine. Note you could also use new DateTimeFormatterBuilder().parseLenient() but this seemed unnecessary.

Secondly I decided to use the optional clause in the format pattern itself. This allows you to specify which parts may not be provided which is exactly the case I was trying to solve.

Leaving us with:

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

This will now handle providing a date with or without time including a T separator, seconds, millis and zone offset.

With any luck this helps someone else!

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
}


来源:https://stackoverflow.com/questions/42903391/convert-simpledateformat-to-datetimeformatter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!