This question already has answers here:
Regex date format validation on Java
(12 answers)
Closed 8 years ago.
I am reading from a file containing lines in the format YYYYMMDD. How can I use regular expressions to check the validity of these lines? Thank you. The application is a Java application.
It is impossible with regex. How will you take leap-years into account? You should try to parse the date. If parse throws an exception the date is wrong:
SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
f.setLenient(false); <-- by default SimpleDateFormat allows 20010132
try {
f.parse(str);
// good
} catch (ParseExcepton e) {
// bad
}
You should better use SimpleDateFormat with setLenient(false); to validate your date string
like Jigar sugested it is better to use DateFormat.
public static boolean isValidDate(String date) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.setLenient(false);
sdf.parse(date);
}
catch (Exception e) {
return false;
}
return true;
}
helpful link
The answers of #EvgeniyDorofeev, #JigarJoshi and #StinePike are right. But I suggest for bulk data processing a slightly different approach to avoid a logic based on expensive ParseException.
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.setLenient(false);
for (String line : lines) { // lines from your source
ParsePosition pos = new ParsePosition(0);
Date date = sdf.parse(line, pos);
boolean valid = (date != null);
// here you can continue with processing the single line
// can even evaluate the line number and error offset in line
}
Just a remark about regular expressions: How do you want to check the gregorian calendrical rules in such a regular expression? Months have different lengths, there are leap years and so on.
For checking date, regular expressions are not effective. But, having said that, if you really want a regular expression, check this link
Related
This question already has answers here:
I have a date in(string) in dd-mon-yyyy format and I want to compare this date with system date
(4 answers)
Closed 3 years ago.
I want to check if input string is valid date or not.
String be like :-
"08-Nov-2011"
"21 Mar 2019"
java code :-
boolean checkFormat;
String input = "08-Nov-2011";
if (input.matches("([0-9]{2})/([0-9]{2})/([0-9]{4})"))
checkFormat=true;
else
checkFormat=false;
System.out.println(checkFormat);
I am thinking of splitting and then check by its length like if first split word be of length 2, second split word be of length 3 and last word be of length 4.
But if Input String be like :-
AB-000-MN89
Then here it will fails.
Please help me to Solve this.
As stated in several comments, the best way to find out if your date is valid is to try to parse it with a java.time.format.DateTimeFormatter to a date object of type LocalDate.
You can support several patterns and/or use built-in ones from the DateTimeFormatter class:
public static void main(String[] args) {
// provide some patterns to be supported (NOTE: there are also built-in patterns!)
List<String> supportedPatterns = new ArrayList<>();
supportedPatterns.add("dd.MMM.yyyy");
supportedPatterns.add("dd MMM yyyy");
supportedPatterns.add("dd-MMM-yyyy");
supportedPatterns.add("dd/MMM/yyyy");
supportedPatterns.add("ddMMMyyyy");
// define some test input
String input = "08-Nov-2011";
// provide a variable for each, pattern and the date
String patternThatWorked = null;
LocalDate output = null;
// try to parse the input with the supported patterns
for (String pattern : supportedPatterns) {
try {
output = LocalDate.parse(input, DateTimeFormatter.ofPattern(pattern));
// until it worked (the line above this comment did not throw an Exception)
patternThatWorked = pattern; // store the pattern that "made your day" and exit the loop
break;
} catch (DateTimeParseException e) {
// no need for anything here but telling the loop to do the next try
continue;
}
}
// check if the parsing was successful (output must have a value)
if (output != null) {
System.out.println("Successfully parsed " + input
+ " to " + output.format(DateTimeFormatter.ISO_LOCAL_DATE) // BUILT-IN pattern!
+ " having used the pattern " + patternThatWorked);
}
}
This outputs
Successfully parsed 08-Nov-2011 to 2011-11-08 having used the pattern dd-MMM-yyyy
You can use SimpleDateFormat with the following pattern: dd-MMM-yyyy. Follow the link to see possible patterns.
SimpleDateFormat may throw ParseException where argument is invalid. So, you can wrap that invocation with a try-catch block.
As an example:
private final String pattern = "dd-MMM-yyyy";
private final SimpleDateFormat sdf = new SimpleDateFormat(pattern);
public boolean validateDate(String date) {
try {
sdf.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
If you have different formats as 08-Nov-2011 and 08 Nov 2011, try to unify them (by removing dashes from the first one, for instance).
A very crude regex for this would be:
\d{2}[- ]\w{3}[- ]\d{4}
08-Nov-2011
21 Mar 2019
Example here: https://regex101.com/r/01vslq/1.
However, it would probably be better to get a regex that don't allow dates like 99-Nov-9999, and so you could try a more thorough one here. However, even better, probably using Java date parsing -- this isn't a great use case for regex if you need to do legitimate date parsing -- for example, February shouldn't allow the numbers 29, 30, 31, and lots of other nuances. Use java.time.DateTimeFormatter (mentioned in the comment above).
This question already has answers here:
How to sanity check a date in Java
(24 answers)
Closed 5 years ago.
I'm programming a window where the user has to type a date on a input field but I don't know how to check if the day or month are coherent or not (like day between 1-31 and month between 1-12)
String string = "26/03/2017";
DateFormat format = new SimpleDateFormat("dd/MM/yyyy") ;
try {
Date date = format.parse(string);
} catch (ParseException e) {
e.printStackTrace();
}
This is the piece of code where I'm formatting the Date, but I have no idea to check what I said before.
Trying to parse a string like this: string = "36/03/2017"; can return a totally legal date object but an incorrect value respect the string.
for that case you can use the lenient flag of the class SimpleDateFormat, setting that flag to false will throw an exception for invalid strings representations of a date (e.g. 29 Feb 2017)
now, you can set the flag Lenient to false, and catch the exception
String string = "36/03/2017";
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
format.setLenient(false);
try {
Date date = format.parse(string);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat has a property which named 'lenient' is default true.
You must set format.setLenient(false) to check validity of the date. if incorrect date is parsed, you get a ParseException.
2017 answer.
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
try {
LocalDate.parse(string, format);
} catch (DateTimeParseException e) {
System.out.println("Not a valid date: " + string);
}
While SimpleDateFormat has two degrees of strictness, lenient and non-lenient, DateTimeFormatter has three, strict, smart and lenient. For validation I recommend strict. Smart is the default, so we need to set it explicitly.
There are many more details in this answer.
I suggest to use regex. For your date format it should be something like:
(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d
You can also find more patterns and validate them here: http://html5pattern.com/Dates
This question already has answers here:
Java: Check the date format of current string is according to required format or not [duplicate]
(8 answers)
Closed 7 years ago.
Hi is there a way to check if an input is a date in Java, the date format is DD/MM/YYYY so int\int\int
I have the basic check if (x != "") but I was wondering if you check that it is a date.
Now I'me getting a new error code:
try {
date = (Date) dateFormat.parse(dateInput);
} catch (ParseException e1) {
System.out.println("FAIL!!!!!!!!");
JOptionPane.showMessageDialog(null, "Date entered is incorrect, please close this window and try again");
new BookApp();
}
The indents probably got messed in when I copied and pasted it, but when the format is wrong it works and the dialog menu pops up. But when I give 12\08\2015 it give a ClassCastError.
How do I get this working?
1) Create a formatter for your date pattern :
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
2) Try to format your String input to a date :
Date date = dateFormat.parse(input);
Now, if the input doesn't match your pattern, you get a ParseException.
You can always try to parse the date and capture if the parse was successful or not.
The SimpleDateFormat will throw an exception if the string was not parsable as a date.
public boolean isDate(String dateString) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
return dateFormat.parse(dateString) != null;
} catch (ParseException e) {
return false;
}
}
I want to check if a String is in certain pattern.
for example i want to check is a String matches the pattern: 2012-02-20.
I.E: xxxx-xx-xx when x is a number.
Is it possible? someone said regular expressions.
use this regex \d{4}-\d{2}-\d{2}
for checking use:
yourString.matches(regexString);
if you want to test if the date string is a valid date, better use SimpleDateFormat to check. don't use regex for that validation, how about month is 13? date is 50? leap years?
some example:
public boolean isValidDate(String dateString) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
df.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
You can do that with the SimpleDateFormat parse method:
final SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
boolean matchesDateFormat(String date)
{
try
{
format.parse(date);
return true;
}
catch(ParseException e)
{
return false;
}
}
Of course, if you later go on to parse the date anyway then you can skip this and just try to parse it.
You can check that the String follow the exact format of 4 digits, a dash -, 2 digits, a dash - and 2 digits with #burning_LEGION's regex. However, it doesn't check whether the String represents a valid date. You can specify 9999-99-99 and it will pass the validation.
Using SimpleDateFormat is the proper method to check that the String is a valid date and it follows a given format of representation. SimpleDateFormat, apart from formatting a date, can also be used to parse Date from String: parse(String), parse(String, ParsePosition).
By default, SimpleDateFormat is lenient, which means it will allow nonsensical dates such as 2013-025-234 to pass. Use setLenient(boolean lenient) to false will solve this problem.
However, another problem is that it will also ignore any garbage data that is after a valid date (e.g. 2012-03-23garbage#$%$#%). Setting lenient doesn't solve this problem. We need to check the last position with parse(String, ParsePosition) method.
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
// Make the parsing strict - otherwise, it is worse than regex solution
dateFormatter.setLenient(false);
Date date = null;
ParsePosition pos = new ParsePosition(0);
date = dateFormatter.parse(inputString, pos);
if (date != null && pos.getIndex() == inputString.length()) {
// These 3 points are ensured:
// - The string only contains the date.
// - The date follows the format strictly.
// - And the date is a valid one.
} else {
// Valid date but string contains other garbage
// Or the string has invalid date or garbage
}
SimpleDateFormat will allow 2013-1-5 to pass, which I think is a reasonable leniency. If you don't want this, you can do a check against the regex before plugging the String into the parse method.
You can check following code:
public void test() {
String REG_EXP = "(\\d{4}-[0,1]?\\d{1}-[0,1,2,3]?\\d{1})"; //yyyy-mm-dd formate this can not check boundary condition something like this... 1981-02-30
String REG_EXP1 = "(\\d{4}-\\d{2}-\\d{2})"; // if u just want xxxx-xx-xx where x is number
String input = "date1 1981-09-06 wrong date 9999-22-22 date2 1981-9-09 date3 1981-11-1 date4";
Pattern pattern = Pattern.compile(REG_EXP);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
Is there a good, strict date parser for Java? I have access to Joda-Time but I have yet to see this option. I found the "Is there a good date parser for Java" question, and while this is related it is sort of the opposite. Whereas that question was asking for a lenient, more fuzzy-logic and prone to human error parser, I would like a strict parser. For example, with both JodaTime (as far as I can tell) and simpleDateFormat, if you have a format "MM/dd/yyyy":
parse this: 40/40/4353
This becomes a valid date. I want a parser that knows that 40 is an invalid month and date. Surely some implementation of this exists in Java?
I don't see that Joda recognizes that as a valid date. Example:
strict = org.joda.time.format.DateTimeFormat.forPattern("MM/dd/yyyy")
try {
strict.parseDateTime('40/40/4353')
assert false
} catch (org.joda.time.IllegalFieldValueException e) {
assert 'Cannot parse "40/40/4353": Value 40 for monthOfYear must be in the range [1,12]' == e.message
}
As best as I can tell, neither does DateFormat with setLenient(false). Example:
try {
df = new java.text.SimpleDateFormat('MM/dd/yyyy')
df.setLenient(false)
df.parse('40/40/4353')
assert false
} catch (java.text.ParseException e) {
assert e.message =~ 'Unparseable'
}
Hope this helps!
A good way to do strict validation with DateFormat is re-formatting the parsed date and checking equality to the original string:
String myDateString = "87/88/9999";
Date myDate = dateFormat.parse(myDateString);
if (!myDateString.equals(df.format(myDate))){
throw new ParseException();
}
Works like a charm.
You can use the apache.commons.validator.routines.DateValidator to validate the date,if you do not want to use SimpleDateFormat.
Example :
public static Date validateDate(String value, String pattern) {
DateValidator validator = new DateValidator();
Date date = null;
if (pattern!=null) { //Pattern is passed
date = validator.validate(value, pattern);
} else {
date = validator.validate(value);
}
return date;
}
So if a null is returned it means that the date is not valid otherwise it's a valid date.This method is an alternative to using the SimpleDateFormat as you don't have to rely on exception being thrown to identify if it's a valid date or not.