Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does SimpleDateFormat parse incorrect date?

Tags:

java

scala

I have date in string format and I want to parse that into util date.

var date ="03/11/2013" 

I am parsing this as :

new SimpleDateFormat("MM/dd/yyyy").parse(date) 

But the strange thing is that, if I am passing "03-08-201309 hjhkjhk" or "03-88-2013" or 43-88-201378", it does not throw error , it parses it.

For this now, I have to write regex pattern for checking whetehr input of date is correct or not. but why is it so ??

Code :

scala> val date="03/88/201309 hjhkjhk" date: java.lang.String = 03/88/201309 hjhkjhk  scala> new SimpleDateFormat("MM/dd/yyyy").parse(date) res5: java.util.Date = Mon May 27 00:00:00 IST 201309 
like image 285
Rishi Avatar asked Mar 11 '13 10:03

Rishi


People also ask

What can I use instead of SimpleDateFormat?

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

Is SimpleDateFormat deprecated?

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

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.

What is the difference between DateFormat and SimpleDateFormat?

The java SimpleDateFormat allows construction of arbitrary non-localized formats. The java DateFormat allows construction of three localized formats each for dates and times, via its factory methods.


1 Answers

You should use DateFormat.setLenient(false):

SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy"); df.setLenient(false); df.parse("03/88/2013"); // Throws an exception 

I'm not sure that will catch everything you want - I seem to remember that even with setLenient(false) it's more lenient than you might expect - but it should catch invalid month numbers for example.

I don't think it will catch trailing text, e.g. "03/01/2013 sjsjsj". You could potentially use the overload of parse which accepts a ParsePosition, then check the current parse index after parsing has completed:

ParsePosition position = new ParsePosition(0); Date date = dateFormat.parse(text, position); if (position.getIndex() != text.length()) {     // Throw an exception or whatever else you want to do } 

You should also look at the Joda Time API which may well allow for a stricter interpretation - and is a generally cleaner date/time API anyway.

like image 68
Jon Skeet Avatar answered Sep 20 '22 16:09

Jon Skeet