Reputation: 157
val dateStr = "2020 10 12 23 12 13"
val dateFormat = "yyyyMMddHHmmss"
import java.util.Date
val sdf = new SimpleDateFormat(dateFormat)
sdf.setLenient(false)
val res = sdf.parse(dateStr)
println("res = "+res)
scala> val res = sdf.parse(dateStr)
java.text.ParseException: Unparseable date: "2020 10 12 23 12 13"
at java.text.DateFormat.parse(DateFormat.java:366)
... 50 elided
The above code block parses and results in an exception, but if i change the "MM" part to "11" instead of "10" then it parses fine, without any exception , but with a wrong date. Any idea why is that ? I want the code to fail or throw an exception if my date String is not in this format "yyyyMMddHHmmss"
/*Note the 11 instead of 10*/
val dateStr = "2020 11 12 23 12 13"
val dateFormat = "yyyyMMddHHmmss"
import java.util.Date
val sdf = new SimpleDateFormat(dateFormat)
sdf.setLenient(false)
val res = sdf.parse(dateStr)
println("res = "+res)
scala> val res = sdf.parse(dateStr)
res: java.util.Date = Wed Jan 01 01:02:23 PST 2020
Upvotes: 1
Views: 241
Reputation: 856
SimpleDateFormat is simply too lenient for what you want. It's parsing your date as:
2020 yyyy
_1 MM (where _ represents a space)
1 dd
_1 HH
2 mm
23 seconds
12 13 ignored
So I think the best way around it for you would be to bite the bullet and forbid spaces.
So try something like trimming the string and then searching for spaces in the middle. If you find spaces, throw an Exception.
But ultimately its probably better to drop SimpleDateFormat and use the new stuff. I think the new DateTimeFormatter class will serve you better:
// In Java
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime date = LocalDateTime.parse(dateStr, formatter);
System.out.println("date="+date);
This throws and exception.
In Scala:
val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
val date = LocalDateTime.parse(dateStr, formatter);
println("date="+date);
Upvotes: 2
Reputation: 338366
The Answer by Ruokki is correct, your formatting pattern does not match your input data.
More importantly, you are using the wrong classes. The date-time classes bundled with the earliest versions of Java are terrible. They were years ago supplanted by the modern java.time classes defined in JSR 310.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu MM dd HH mm ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
To detect faulty inputs, trap for the DateTimeParseException
.
try
{
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
}
catch ( DateTimeParseException e )
{
…
}
ResolverStyle
The DateTimeFormatter
uses one of three different approaches in parsing: strict, smart and lenient. These are represented by the ResolverStyle
enum. SMART
is used by default, but you can specify STRICT
if that better suits your needs.
I suggest you educate the publisher of your input data about ISO 8601. That standard defines formats for exchanging date-time values textually.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to define a formatting pattern for compliant inputs.
Upvotes: 2
Reputation: 957
Hello I think the problem is the date format:
val dateFormat = "yyyyMMddHHmmss"
And should be
val dateFormat = "yyyy MM dd HH mm ss"
Because your dateStr contains some space who play a important part in the format
But if you want to fail in case you have space or other thing unwanted in the date maybe a regex is the best answer ?
Upvotes: 0