Check the actual date and time at parse with Java's SimpleDateFormat

Non-existent dates are parsed

Sample with minimal coding.

normal


String target = "2019/07/20 12:34:56";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
try{
    Date result = sdf.parse(target);
    System.out.println(sdf.format(result));
}catch(ParseException e){
    e.printStackTrace();
}
2019/07/20 12:34:56

Parse and format are executed according to the entered String value.

Here, we will verify the behavior when the value of String is set to 2020/27/72 72: 72: 72. In a process that generally parses, like this value, a non-existent date and time, Date and time data that cannot be displayed on the calendar or clock You want to make the parse fail as an abnormal input. This article is written for that requirement.

abnormal


String target = "2020/27/72 72:72:72";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
try {
    Date result = sdf.parse(target);
    System.out.println(sdf.format(result));
} catch (ParseException e) {
    e.printStackTrace();
}
2022/05/14 01:13:12

In terms of behavior, the conversion is done just like that without throwing a ParseException.

I don't want to parse such data

It is possible to verify whether the date and time actually exist by adding only one step.

1 step added


String target = "2020/27/72 72:72:72";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
/* setLinient(boolean)Add a call to*/
sdf.setLenient(false);
try {
    Date result = sdf.parse(target);
    System.out.println(sdf.format(result));
} catch (ParseException e) {
    e.printStackTrace();
}
java.text.ParseException: Unparseable date: "2020/27/72 72:72:72"
	at java.text.DateFormat.parse(DateFormat.java:366)
	at ...

It will throw a ParseException, so As with other cases of invalid input values (in this implementation example, " July 20, 1st year of Reiwa "), You can deal with it by picking up exceptions. How to deal with it depends on the implementation requirements, so I will not touch it.

If you want to know how to deal with coding, this is the end. After this, I tried to search the background of the called method for a while.


2020/27/72 72:72:72 = 2022/05/14 01:13:12? A light explanation of why the data given in the code example above is at this date and time. Check only the time part of the date and time. 72:00 = 24 hours x 3 72 minutes = 60 minutes x 1 + 12 minutes 72 seconds = 60 seconds x 1 + 12 seconds → (12 seconds + 1 minute) + (12 minutes + 1 hour) + 3 days → 12 seconds + 13 minutes + 1 hour Similarly, three days' worth of renormalization is performed up to the date part, and the amount overflowing from each month is included.

Confirmation of description in Java specifications

Verify the description in Java8 API (SimpleDateFormat).

Check specifications for the number of digits in the input value

Because " yyyy / MM / dd HH: mm: ss " is specified as the format, MM is 2 digits, dd is also 2 digits ... Otherwise, it will be NG? It's like an illusion, so check it.

input


SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
sdf.setLenient(false);
String zeropad = "2019/01/02 03:04:05";  //The 1-digit part is also padded with 0 so that it becomes 2 digits.
String lessdig = "2019/1/2 3:4:5";   //No zero padding for 1 digit
try{
    sdf.parse(zeropad);
    sdf.parse(lessdig);
...
(ParseException does not occur)

This behavior is described in the API.

Numeric: When formatting, the number of pattern characters is the minimum number of digits. Numbers shorter than this are zero-padded to this number of digits. The number of pattern characters is ignored for parsing unless you need to separate two adjacent fields.

** The number of characters is ignored **.

Existence date and time check specifications of input values

For the default date check of parse (String) (expression such as "strict parsing" on API), It was described in DateFormat API, which is a superclass of SimpleDateFormat.

By default, the analysis is not rigorous. If the input is not in the format used by this object's format method, but can be parsed as a date, then the parse is successful.

SimpleDateFormat.parse(String) → DateFormat.parse(String) → DateFormat.parse(String, ParsePosition) I was able to come to the description in the flow.

Following the description of this API and the above sentence, it was written like this.

The client can strictly request this format by calling setLenient (false).

I see, API is the strongest document.

Who is setLenient (false)

In conclusion, it's a method of the Calendar class. Calendar.setLinient(boolean)

Set whether to interpret the date / time strictly. (Omitted) The default is non-strict.

If this allows non-strictness, pass true, if it does strictly, pass false as an argument. Because the word lenient means "loose" It corresponds to the arguments "loose (true)" and "not loose (false)".

Real date check can be easily implemented with setLenient ()

To repeat in a nutshell

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
sdf.setLenient(false);

Only rigorous date analysis is done.

Recommended Posts

Check the actual date and time at parse with Java's SimpleDateFormat
Sample code to parse date and time with Java SimpleDateFormat
Set the date and time from the character string with POI
Check when moss with SimpleDateFormat parse
The design concept of Java's Date and Time API is interesting
Draw a bar graph and a line graph at the same time with MPAndroidChart
Date and time
Format the date and time given by created_at
Parse the date and time string formatted by the C asctime function in Java
Speed comparison at the time of generation at the time of date conversion
Behavior noticed when adding RadioButton and initial check at the same time in code
[Rails] Precautions when comparing date and time with DateTime
Form and process file and String data at the same time with Spring Boot + Java
Handle Java 8 date and time API with Thymeleaf with Spring Boot
What is the LocalDateTime class? [Java beginner] -Date and time class-
[Java] Check the difference between orElse and orElseGet with IntStream
[Java] Use ResolverStyle.LENIENT to handle the date and time nicely
[Rails] Get access_token at the time of Twitter authentication with Sorcery and save it in DB
Get the current date and time by specifying the time zone in Thymeleaf
Setting to start multiple units at the same time with Vagrant
The relationship between strict Java date checking and daylight savings time
[MySQL] [java] Receive date and time
Check date correlation with Spring Boot
Beginners create web applications with Java and MySQL (adding at any time)
[Spring Boot] Post files and other data at the same time [Axios]
[Java] How to get the current date and time and specify the display format
Email sending function with Action Mailer at the time of new registration
[Android] Check the actual device without moving your hand with automatic scrolling
I was stuck with the handling of the time zone when formatting with SimpleDateFormat