Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat doesn't work as expected [duplicate]

I try to use this function but it doesn't work with this case '12/05/201a' somebody knows why happen this?

In my test I use this System.out.println(isThisDateValid("12/05/201a", "dd/MM/yyyy")); and the answer was true but I'm expected the result would be false because year contains letters.

 public static boolean isThisDateValid(String dateToValidate, String dateFromat)
    {

        if (dateToValidate == null)
        {
            return false;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
        sdf.setLenient(false);

        try
        {

            //if not valid, it will throw ParseException
            Date date = sdf.parse(dateToValidate);
            System.out.println(date);

        } catch (ParseException e)
        {

            e.printStackTrace();
            return false;
        }

        return true;
    }
like image 906
kakashy Avatar asked Jul 27 '15 16:07

kakashy


People also ask

Is SimpleDateFormat deprecated?

Deprecated. A class for parsing and formatting dates with a given pattern, compatible with the Java 6 API.

What can I use instead of SimpleDateFormat?

DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.

Why is SimpleDateFormat not thread-safe?

2.2.Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally. So SimpleDateFormat instances are not thread-safe, and we should use them carefully in concurrent environments.

Is SimpleDateFormat can be used in multithreaded environment?

Java's SimpleDateFormat is not thread-safe, Use carefully in multi-threaded environments. SimpleDateFormat is used to format and parse dates in Java. You can create an instance of SimpleDateFormat with a date-time pattern like yyyy-MM-dd HH:mm:ss , and then use that instance to format and parse dates to/from string.


1 Answers

DateFormat#parse doesn't necessarily use the entire string:

Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.

(my emphasis)

SimpleDateFormat's docs tell us that yyyy doesn't necessarily mean it will require four digits for a year:

Year:

...

  • For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

So it's correct (if possibly surprising) that it parses that string in the year 201.

You can use parse(String,ParsePosition) to figure out whether the entire string has been consumed, or validate it with a regular expression before parsing. Here's a version that will check that the whole string has been parsed, and not just the first characters:

public static boolean isThisDateValid(String dateToValidate, String dateFormat) {
    if (dateToValidate == null) {
        return false;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    sdf.setLenient(false);

    ParsePosition position = new ParsePosition(0);
    Date date = sdf.parse(dateToValidate, position);
    return date != null && position.getIndex() == dateToValidate.length();
}
like image 198
JB Nizet Avatar answered Oct 21 '22 20:10

JB Nizet