Fastest way to tell if a string is a valid date

前端 未结 8 1156
故里飘歌
故里飘歌 2020-12-13 04:52

I am supporting a common library at work that performs many checks of a given string to see if it is a valid date. The Java API, commons-lang library, and JodaTime all have

8条回答
  •  心在旅途
    2020-12-13 05:21

    This is my way to check if the date is in correct format and is actually a valid date. Presume we do not need SimpleDateFormat to convert incorrect to date to a correct one but instead a method just returns false. Output to console is used only to check how the method works on each step.

    public class DateFormat {
    
    public static boolean validateDateFormat(String stringToValidate){
        String sdf = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat format=new SimpleDateFormat(sdf);   
        String dateFormat = "[12]{1,1}[0-9]{3,3}-(([0]{0,1}[1-9]{1,1})|([1]{0,1}[0-2]{1,1}))-(([0-2]{0,1}[1-9]{1,1})|([3]{0,1}[01]{1,1}))[ ](([01]{0,1}[0-9]{1,1})|([2]{0,1}[0-3]{1,1}))((([:][0-5]{0,1}[0-9]{0,1})|([:][0-5]{0,1}[0-9]{0,1}))){0,2}";
        boolean isPassed = false;
    
        isPassed = (stringToValidate.matches(dateFormat)) ? true : false;
    
    
        if (isPassed){
            // digits are correct. Now, check that the date itself is correct
            // correct the date format to the full date format
            String correctDate = correctDateFormat(stringToValidate);
            try
            {
                Date d = format.parse(correctDate);
                isPassed = (correctDate.equals(new SimpleDateFormat(sdf).format(d))) ? true : false;
                System.out.println("In = " + correctDate + "; Out = " 
                        + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d) + " equals = " 
                        + (correctDate.equals(new SimpleDateFormat(sdf).format(d))));
                // check that are date is less than current
                if (!isPassed || d.after(new Date())) {
                    System.out.println(new SimpleDateFormat(sdf).format(d) + " is after current day " 
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                    isPassed = false;
                } else {
                    isPassed = true;
                }
            } catch (ParseException e) {
                System.out.println(correctDate + " Exception! " + e.getMessage());
                isPassed = false;
            }
        } else {
            return false;
        }
        return isPassed;
    }
    
    /**
     *  method to fill up the values that are not full, like 2 hours -> 02 hours
     *  to avoid undesirable difference when we will compare original date with parsed date with SimpleDateFormat
     */
    private static String correctDateFormat(String stringToValidate) {
        String correctDate = "";
        StringTokenizer stringTokens = new StringTokenizer(stringToValidate, "-" + " " + ":", false);
        List tokens = new ArrayList<>();
        System.out.println("Inside of recognizer");
        while (stringTokens.hasMoreTokens()) {
            String token = stringTokens.nextToken();
            tokens.add(token);
            // for debug
            System.out.print(token + "|");
        }
        for (int i=0; i

    }

    A JUnit test for that:

    import static org.junit.Assert.*;
    import junitparams.JUnitParamsRunner;
    import junitparams.Parameters;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    
    @RunWith(JUnitParamsRunner.class)
    public class DateFormatTest {
    
        @Parameters
        private static final Object[] getCorrectDate() {
            return new Object[] {
                    new Object[]{"2014-12-13 12:12:12"},
                    new Object[]{"2014-12-13 12:12:1"},
                    new Object[]{"2014-12-13 12:12:01"},
                    new Object[]{"2014-12-13 12:1"},
                    new Object[]{"2014-12-13 12:01"},
                    new Object[]{"2014-12-13 12"},
                    new Object[]{"2014-12-13 1"},
                    new Object[]{"2014-12-31 12:12:01"},
                    new Object[]{"2014-12-30 23:59:59"},
            };
        }
        @Parameters
        private static final Object[] getWrongDate() {
            return new Object[] {
                    new Object[]{"201-12-13 12:12:12"},
                    new Object[]{"2014-12- 12:12:12"},
                    new Object[]{"2014- 12:12:12"},
                    new Object[]{"3014-12-12 12:12:12"},
                    new Object[]{"2014-22-12 12:12:12"},
                    new Object[]{"2014-12-42 12:12:12"},
                    new Object[]{"2014-12-32 12:12:12"},
                    new Object[]{"2014-13-31 12:12:12"},
                    new Object[]{"2014-12-31 32:12:12"},
                    new Object[]{"2014-12-31 24:12:12"},
                    new Object[]{"2014-12-31 23:60:12"},
                    new Object[]{"2014-12-31 23:59:60"},
                    new Object[]{"2014-12-31 23:59:50."},
                    new Object[]{"2014-12-31 "},
                    new Object[]{"2014-12 23:59:50"},
                    new Object[]{"2014 23:59:50"}
            };
        }
    
        @Test
        @Parameters(method="getCorrectDate")
        public void testMethodHasReturnTrueForCorrectDate(String dateToValidate) {
            assertTrue(DateFormat.validateDateFormatSimple(dateToValidate));
        }
    
        @Test
        @Parameters(method="getWrongDate")
        public void testMethodHasReturnFalseForWrongDate(String dateToValidate) {
            assertFalse(DateFormat.validateDateFormat(dateToValidate));
        }
    
    }
    

提交回复
热议问题