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
.
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.
Verify the description in Java8 API (SimpleDateFormat).
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 **.
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.
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)".
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