Recently, I met a requirement that there is a column of date in the Excel table, but the format of the date is not certain. The product hopes to read all the dates in all formats, save them in the same format and input them into the database.

The first solution that comes to mind is to use regular expressions to do matching. As I write more and more, I want to give up (and regular expressions themselves have complex rules and are not easy to write). In consideration of the poor performance of regular expressions, I give up this method. I think this scene should be more common, so I searched whether there is a good solution to the god, query for a long time, did not find such an introduction, of course, in my painstaking search, or in a corner to find a solution provided by the god. Here’s the code:

    private static final String[] DATE_PATTERN_ARRAY = {
            defaultDatePattern,
            "yyyy/MM/dd"."yyyy-MM-dd"."yyyy.MM.dd"."yyyy/MM/d"."yyyy/M/dd"."yyyy/M/d"."Yyyy year MM month DD day"
    };

    private static String mergePattern = "";

    /** * use multiple patterns to try to parse the date **@param inputDate inputDate
     * @return Date
     */
    public static LocalDate commonParse(String inputDate) {
        if (StringUtils.isBlank(inputDate)) {
            return null;
        }
        if (StringUtils.isBlank(mergePattern)) {
            mergePattern = Arrays.stream(DATE_PATTERN_ARRAY).map(val -> "[" + val + "]").collect(Collectors.joining());
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(mergePattern);
        try {
            return LocalDate.parse(inputDate, formatter);
        } catch (Exception e) {
            log.error("parse error", e);
        }
        return null;
    }
Copy the code

Test cases:

    @Test
    public void testCommonParse(a) {
        String[] dateArray = new String[]{
                "2021/01/01"."20210101"."2021-01-01"."2021.01.01"."2021/01/1"."2021/1/01"."2021/1/1"."January 1, 2021"};
        for(String date : dateArray) { LocalDate result = DateFormatUtils.commonParse(date); Assert.assertNotNull(result); System.out.println(result); }}Copy the code

Output:

2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
2021-01-01
    
Copy the code

In my own computer tests, the average time is around 160ms, which is still quite long. Note that this multi-format parsing logic is still quite complex, in the case of not forced, or not recommended.

Record, by the way if you want to parse the date, you can use this tool: org.apache.com mons: Commons – lang, the name of the class: org.apache.com mons. Lang. Time. DateUtils

    /**
     * <p>Parses a string representing a date by trying a variety of different parsers.</p>
     * 
     * <p>The parse will try each parse pattern in turn.
     * A parse is only deemed successful if it parses the whole of the input string.
     * If no parse patterns match, a ParseException is thrown.</p>
     * The parser will be lenient toward the parsed date.
     * 
     * @param str  the date to parse, not null
     * @param parsePatterns  the date format patterns to use, see SimpleDateFormat, not null
     * @return the parsed date
     * @throws IllegalArgumentException if the date string or pattern array is null
     * @throws ParseException if none of the date patterns were suitable (or there were none)
     */
    public static Date parseDate(String str, String[] parsePatterns) throws ParseException {
        return parseDateWithLeniency(str, parsePatterns, true);
    }
Copy the code