Determine if a String is a valid date before parsing

后端 未结 12 1650
半阙折子戏
半阙折子戏 2020-12-03 11:36

I have this situation where I am reading about 130K records containing dates stored as String fields. Some records contain blanks (nulls), some contain strings like this: \'

12条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-03 11:57

    On one hand I see nothing wrong with your use of try/catch for the purpose, it’s the option I would use. On the other hand there are alternatives:

    1. Take a taste from the string before deciding how to parse it.
    2. Use optional parts of the format pattern string.

    For my demonstrations I am using java.time, the modern Java date and time API, because the Date class used in the question was always poorly designed and is now long outdated. For a date without time of day we need a java.time.LocalDate.

    try-catch

    Using try-catch with java.time looks like this:

        DateTimeFormatter ddmmmuuFormatter = DateTimeFormatter.ofPattern("dd-MMM-uu", Locale.ENGLISH);
        DateTimeFormatter ddmmuuuuFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    
        String dateString = "07-Jun-09";
    
        LocalDate result;
        try {
            result = LocalDate.parse(dateString, ddmmmuuFormatter);
        } catch (DateTimeParseException dtpe) {
            result = LocalDate.parse(dateString, ddmmuuuuFormatter);
        }
        System.out.println("Date: " + result);
    

    Output is:

    Date: 2009-06-07

    Suppose instead we defined the string as:

        String dateString = "07/06/2009";
    

    Then output is still the same.

    Take a taste

    If you prefer to avoid the try-catch construct, it’s easy to make a simple check to decide which of the formats your string conforms to. For example:

        if (dateString.contains("-")) {
            result = LocalDate.parse(dateString, ddmmmuuFormatter);
        } else {
            result = LocalDate.parse(dateString, ddmmuuuuFormatter);
        }
    

    The result is the same as before.

    Use optional parts in the format pattern string

    This is the option I like the least, but it’s short and presented for some measure of completeness.

        DateTimeFormatter dateFormatter
                = DateTimeFormatter.ofPattern("[dd-MMM-uu][dd/MM/uuuu]", Locale.ENGLISH);
        LocalDate result = LocalDate.parse(dateString, dateFormatter);
    

    The square brackets denote optional parts of the format. So Java first tries to parse using dd-MMM-uu. No matter if successful or not it then tries to parse the remainder of the string using dd/MM/uuuu. Given your two formats one of the attempts will succeed, and you have parsed the date. The result is still the same as above.

    Link

    Oracle tutorial: Date Time explaining how to use java.time.

提交回复
热议问题