Related
I find it curious that the most obvious way to create Date objects in Java has been deprecated and appears to have been "substituted" with a not so obvious to use lenient calendar.
How do you check that a date, given as a combination of day, month, and year, is a valid date?
For instance, 2008-02-31 (as in yyyy-mm-dd) would be an invalid date.
Key is df.setLenient(false);. This is more than enough for simple cases. If you are looking for a more robust (I doubt that) and/or alternate libraries like joda-time, then look at the answer by user "tardate"
final static String DATE_FORMAT = "dd-MM-yyyy";
public static boolean isDateValid(String date)
{
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
As shown by #Maglob, the basic approach is to test the conversion from string to date using SimpleDateFormat.parse. That will catch invalid day/month combinations like 2008-02-31.
However, in practice that is rarely enough since SimpleDateFormat.parse is exceedingly liberal. There are two behaviours you might be concerned with:
Invalid characters in the date string
Surprisingly, 2008-02-2x will "pass" as a valid date with locale format = "yyyy-MM-dd" for example. Even when isLenient==false.
Years: 2, 3 or 4 digits?
You may also want to enforce 4-digit years rather than allowing the default SimpleDateFormat behaviour (which will interpret "12-02-31" differently depending on whether your format was "yyyy-MM-dd" or "yy-MM-dd")
A Strict Solution with the Standard Library
So a complete string to date test could look like this: a combination of regex match, and then a forced date conversion. The trick with the regex is to make it locale-friendly.
Date parseDate(String maybeDate, String format, boolean lenient) {
Date date = null;
// test date string matches format structure using regex
// - weed out illegal characters and enforce 4-digit year
// - create the regex based on the local format string
String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {
// date string matches format structure,
// - now test it can be converted to a valid date
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
sdf.applyPattern(format);
sdf.setLenient(lenient);
try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
}
return date;
}
// used like this:
Date date = parseDate( "21/5/2009", "d/M/yyyy", false);
Note that the regex assumes the format string contains only day, month, year, and separator characters. Aside from that, format can be in any locale format: "d/MM/yy", "yyyy-MM-dd", and so on. The format string for the current locale could be obtained like this:
Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();
Joda Time - Better Alternative?
I've been hearing about joda time recently and thought I'd compare. Two points:
Seems better at being strict about invalid characters in the date string, unlike SimpleDateFormat
Can't see a way to enforce 4-digit years with it yet (but I guess you could create your own DateTimeFormatter for this purpose)
It's quite simple to use:
import org.joda.time.format.*;
import org.joda.time.DateTime;
org.joda.time.DateTime parseDate(String maybeDate, String format) {
org.joda.time.DateTime date = null;
try {
DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
date = fmt.parseDateTime(maybeDate);
} catch (Exception e) { }
return date;
}
tl;dr
Use the strict mode on java.time.DateTimeFormatter to parse a LocalDate. Trap for the DateTimeParseException.
LocalDate.parse( // Represent a date-only value, without time-of-day and without time zone.
"31/02/2000" , // Input string.
DateTimeFormatter // Define a formatting pattern to match your input string.
.ofPattern ( "dd/MM/uuuu" )
.withResolverStyle ( ResolverStyle.STRICT ) // Specify leniency in tolerating questionable inputs.
)
After parsing, you might check for reasonable value. For example, a birth date within last one hundred years.
birthDate.isAfter( LocalDate.now().minusYears( 100 ) )
Avoid legacy date-time classes
Avoid using the troublesome old date-time classes shipped with the earliest versions of Java. Now supplanted by the java.time classes.
LocalDate & DateTimeFormatter & ResolverStyle
The LocalDate class represents a date-only value without time-of-day and without time zone.
String input = "31/02/2000";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" );
try {
LocalDate ld = LocalDate.parse ( input , f );
System.out.println ( "ld: " + ld );
} catch ( DateTimeParseException e ) {
System.out.println ( "ERROR: " + e );
}
The java.time.DateTimeFormatter class can be set to parse strings with any of three leniency modes defined in the ResolverStyle enum. We insert a line into the above code to try each of the modes.
f = f.withResolverStyle ( ResolverStyle.LENIENT );
The results:
ResolverStyle.LENIENTld: 2000-03-02
ResolverStyle.SMARTld: 2000-02-29
ResolverStyle.STRICTERROR: java.time.format.DateTimeParseException: Text '31/02/2000' could not be parsed: Invalid date 'FEBRUARY 31'
We can see that in ResolverStyle.LENIENT mode, the invalid date is moved forward an equivalent number of days. In ResolverStyle.SMART mode (the default), a logical decision is made to keep the date within the month and going with the last possible day of the month, Feb 29 in a leap year, as there is no 31st day in that month. The ResolverStyle.STRICT mode throws an exception complaining that there is no such date.
All three of these are reasonable depending on your business problem and policies. Sounds like in your case you want the strict mode to reject the invalid date rather than adjust it.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
You can use SimpleDateFormat
For example something like:
boolean isLegalDate(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
return sdf.parse(s, new ParsePosition(0)) != null;
}
The current way is to use the calendar class. It has the setLenient method that will validate the date and throw and exception if it is out of range as in your example.
Forgot to add:
If you get a calendar instance and set the time using your date, this is how you get the validation.
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
cal.getTime();
}
catch (Exception e) {
System.out.println("Invalid date");
}
java.time
With the Date and Time API (java.time classes) built into Java 8 and later, you can use the LocalDate class.
public static boolean isDateValid(int year, int month, int day) {
try {
LocalDate.of(year, month, day);
} catch (DateTimeException e) {
return false;
}
return true;
}
Building on Aravind's answer to fix the problem pointed out by ceklock in his comment, I added a method to verify that the dateString doesn't contain any invalid character.
Here is how I do:
private boolean isDateCorrect(String dateString) {
try {
Date date = mDateFormatter.parse(dateString);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return matchesOurDatePattern(dateString); //added my method
}
catch (ParseException e) {
return false;
}
}
/**
* This will check if the provided string matches our date format
* #param dateString
* #return true if the passed string matches format 2014-1-15 (YYYY-MM-dd)
*/
private boolean matchesDatePattern(String dateString) {
return dateString.matches("^\\d+\\-\\d+\\-\\d+");
}
An alternative strict solution using the standard library is to perform the following:
1) Create a strict SimpleDateFormat using your pattern
2) Attempt to parse the user entered value using the format object
3) If successful, reformat the Date resulting from (2) using the same date format (from (1))
4) Compare the reformatted date against the original, user-entered value. If they're equal then the value entered strictly matches your pattern.
This way, you don't need to create complex regular expressions - in my case I needed to support all of SimpleDateFormat's pattern syntax, rather than be limited to certain types like just days, months and years.
I suggest you to use org.apache.commons.validator.GenericValidator class from apache.
GenericValidator.isDate(String value, String datePattern, boolean strict);
Note: strict - Whether or not to have an exact match of the datePattern.
I think the simpliest is just to convert a string into a date object and convert it back to a string. The given date string is fine if both strings still match.
public boolean isDateValid(String dateString, String pattern)
{
try
{
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
if (sdf.format(sdf.parse(dateString)).equals(dateString))
return true;
}
catch (ParseException pe) {}
return false;
}
Assuming that both of those are Strings (otherwise they'd already be valid Dates), here's one way:
package cruft;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateValidator
{
private static final DateFormat DEFAULT_FORMATTER;
static
{
DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
DEFAULT_FORMATTER.setLenient(false);
}
public static void main(String[] args)
{
for (String dateString : args)
{
try
{
System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
}
catch (ParseException e)
{
System.out.println("could not parse " + dateString);
}
}
}
public static Date convertDateString(String dateString) throws ParseException
{
return DEFAULT_FORMATTER.parse(dateString);
}
}
Here's the output I get:
java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011
Process finished with exit code 0
As you can see, it does handle both of your cases nicely.
This is working great for me. Approach suggested above by Ben.
private static boolean isDateValid(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
Date d = asDate(s);
if (sdf.format(d).equals(s)) {
return true;
} else {
return false;
}
} catch (ParseException e) {
return false;
}
}
looks like SimpleDateFormat is not checking the pattern strictly even after setLenient(false); method is applied on it, so i have used below method to validate if the date inputted is valid date or not as per supplied pattern.
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public boolean isValidFormat(String dateString, String pattern) {
boolean valid = true;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
try {
formatter.parse(dateString);
} catch (DateTimeParseException e) {
valid = false;
}
return valid;
}
Two comments on the use of SimpleDateFormat.
it should be declared as a static instance
if declared as static access should be synchronized as it is not thread safe
IME that is better that instantiating an instance for each parse of a date.
Above methods of date parsing are nice , i just added new check in existing methods that double check the converted date with original date using formater, so it works for almost each case as i verified. e.g. 02/29/2013 is invalid date.
Given function parse the date according to current acceptable date formats. It returns true if date is not parsed successfully.
public final boolean validateDateFormat(final String date) {
String[] formatStrings = {"MM/dd/yyyy"};
boolean isInvalidFormat = false;
Date dateObj;
for (String formatString : formatStrings) {
try {
SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
sdf.applyPattern(formatString);
sdf.setLenient(false);
dateObj = sdf.parse(date);
System.out.println(dateObj);
if (date.equals(sdf.format(dateObj))) {
isInvalidFormat = false;
break;
}
} catch (ParseException e) {
isInvalidFormat = true;
}
}
return isInvalidFormat;
}
Here's what I did for Node environment using no external libraries:
Date.prototype.yyyymmdd = function() {
var yyyy = this.getFullYear().toString();
var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
var dd = this.getDate().toString();
return zeroPad([yyyy, mm, dd].join('-'));
};
function zeroPad(date_string) {
var dt = date_string.split('-');
return dt[0] + '-' + (dt[1][1]?dt[1]:"0"+dt[1][0]) + '-' + (dt[2][1]?dt[2]:"0"+dt[2][0]);
}
function isDateCorrect(in_string) {
if (!matchesDatePattern) return false;
in_string = zeroPad(in_string);
try {
var idate = new Date(in_string);
var out_string = idate.yyyymmdd();
return in_string == out_string;
} catch(err) {
return false;
}
function matchesDatePattern(date_string) {
var dateFormat = /[0-9]+-[0-9]+-[0-9]+/;
return dateFormat.test(date_string);
}
}
And here is how to use it:
isDateCorrect('2014-02-23')
true
// to return valid days of month, according to month and year
int returnDaysofMonth(int month, int year) {
int daysInMonth;
boolean leapYear;
leapYear = checkLeap(year);
if (month == 4 || month == 6 || month == 9 || month == 11)
daysInMonth = 30;
else if (month == 2)
daysInMonth = (leapYear) ? 29 : 28;
else
daysInMonth = 31;
return daysInMonth;
}
// to check a year is leap or not
private boolean checkLeap(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
Here is I would check the date format:
public static boolean checkFormat(String dateTimeString) {
return dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}") || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")
|| dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}") || dateTimeString
.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") ||
dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}Z");
}
public static String detectDateFormat(String inputDate, String requiredFormat) {
String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
String dateFormat;
if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
dateFormat = "MMddyyyy";
} else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
dateFormat = "ddMMyyyy";
} else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
dateFormat = "yyyyMMdd";
} else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
dateFormat = "yyyyddMM";
} else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
dateFormat = "ddMMMyyyy";
} else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
dateFormat = "MMMddyyyy";
} else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
dateFormat = "yyyyMMMdd";
} else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
dateFormat = "yyyyddMMM";
} else {
return "Pattern Not Added";
//add your required regex
}
try {
String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));
return formattedDate;
} catch (Exception e) {
//
return "";
}
}
setLenient to false if you like a strict validation
public boolean isThisDateValid(String dateToValidate, String dateFromat){
if(dateToValidate == null){
return false;
}
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);
try {
//if not valid, it will throw ParseException
Date date = sdf.parse(dateToValidate);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
return false;
}
return true;
}
With 'legacy' date format, we can format the result and compare it back to the source.
public boolean isValidFormat(String source, String pattern) {
SimpleDateFormat sd = new SimpleDateFormat(pattern);
sd.setLenient(false);
try {
Date date = sd.parse(source);
return date != null && sd.format(date).equals(source);
} catch (Exception e) {
return false;
}
}
This execerpt says 'false' to source=01.01.04 with pattern '01.01.2004'
We can use the org.apache.commons.validator.GenericValidator's method directly without adding the whole library:
public static boolean isValidDate(String value, String datePattern, boolean strict) {
if (value == null
|| datePattern == null
|| datePattern.length() <= 0) {
return false;
}
SimpleDateFormat formatter = new SimpleDateFormat(datePattern, Locale.ENGLISH);
formatter.setLenient(false);
try {
formatter.parse(value);
} catch(ParseException e) {
return false;
}
if (strict && (datePattern.length() != value.length())) {
return false;
}
return true;
}
A simple and elegant way for Android developers (Java 8 not required):
// month value is 1-based. e.g., 1 for January.
public static boolean isDateValid(int year, int month, int day) {
Calendar calendar = Calendar.getInstance();
try {
calendar.setLenient(false);
calendar.set(year, month-1, day);
calendar.getTime();
return true;
} catch (Exception e) {
return false;
}
}
Below code works with dd/MM/yyyy format and can be used to check NotNull,NotEmpty as well.
public static boolean validateJavaDate(String strDate) {
if (strDate != null && !strDate.isEmpty() && !strDate.equalsIgnoreCase(" ")) {
{
SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
date.setLenient(false);
try {
Date javaDate = date.parse(strDate);
System.out.println(strDate + " Valid Date format");
}
catch (ParseException e) {
System.out.println(strDate + " Invalid Date format");
return false;
}
return true;
}
} else {
System.out.println(strDate + "----> Date is Null/Empty");
return false;
}
}
I'm running into a problem where I can change my String to a Date but I can't retrieve the data because it's in a try/catch block :
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM");
try {
Date date = formatter.parse(input);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
Any ideas on how I can retrieve the data?
Additional info: The project is to have someone input his day and month of birth so the program can go check on an Excel sheet what his astrological sign is. Do I need to convert the input to a date or am I banging my head against a wall?
Declare your date before the try/catch:
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM");
Date date = null;
try {
date = formatter.parse(input);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
Declare date outside the try-catch-block and fill it inside the block. Afterwards the data will be in the variable, or not, depending on whether and at what point the try failed. This means you'll have to be prepared that it isn't filled and check for null etc.
Date date = null;
try {
date = formatter.parse(input);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
if (date != null) { doSomething(date); }
You can declare date outside the try block as in the other answers; however, since you almost certainly need a valid value to proceed anyway, you should probably just include the code for processing it in the try block as well. I.e.:
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM");
try {
Date date = formatter.parse(input);
System.out.println(formatter.format(date));
// do whatever you need with date here...
} catch (ParseException e) {
e.printStackTrace();
}
This question already has answers here:
How to sanity check a date in Java
(24 answers)
Closed 4 years ago.
I wanted to know that is there any method available in Java that can do this.Otherwise I may go for Regex solution.
I have input string from user that can be any characters. And I want to check that the input string is according to my required date format or not.
As I have input 20130925 and my required format is dd/MM/yyyy so, for this case I should get false.
I don't want to convert this date I just want to check whether input string is according to required date format or not.
I have tried following
Date date = null;
try {
date = new SimpleDateFormat("dd/MM/yyyy").parse("20130925");
} catch (Exception ex) {
// do something for invalid dateformat
}
but my catch (Exception ex) block is unable to catch any exceptions generated by SimpleDateFormat.Parse();
Disclaimer
Parsing a string back to date/time value in an unknown format is inherently impossible (let's face it, what does 3/3/3 actually mean?!), all we can do is "best effort"
Important
This solution doesn't throw an Exception, it returns a boolean, this is by design. Any Exceptions are used purely as a guard mechanism.
2018
Since it's now 2018 and Java 8+ has the date/time API (and the rest have the ThreeTen backport). The solution remains basically the same, but becomes slightly more complicated, as we need to perform checks for:
date and time
date only
time only
This makes it look something like...
public static boolean isValidFormat(String format, String value, Locale locale) {
LocalDateTime ldt = null;
DateTimeFormatter fomatter = DateTimeFormatter.ofPattern(format, locale);
try {
ldt = LocalDateTime.parse(value, fomatter);
String result = ldt.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException e) {
try {
LocalDate ld = LocalDate.parse(value, fomatter);
String result = ld.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException exp) {
try {
LocalTime lt = LocalTime.parse(value, fomatter);
String result = lt.format(fomatter);
return result.equals(value);
} catch (DateTimeParseException e2) {
// Debugging purposes
//e2.printStackTrace();
}
}
}
return false;
}
This makes the following...
System.out.println("isValid - dd/MM/yyyy with 20130925 = " + isValidFormat("dd/MM/yyyy", "20130925", Locale.ENGLISH));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 = " + isValidFormat("dd/MM/yyyy", "25/09/2013", Locale.ENGLISH));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = " + isValidFormat("dd/MM/yyyy", "25/09/2013 12:13:50", Locale.ENGLISH));
System.out.println("isValid - yyyy-MM-dd with 2017-18--15 = " + isValidFormat("yyyy-MM-dd", "2017-18--15", Locale.ENGLISH));
output...
isValid - dd/MM/yyyy with 20130925 = false
isValid - dd/MM/yyyy with 25/09/2013 = true
isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = false
isValid - yyyy-MM-dd with 2017-18--15 = false
Original Answer
Simple try and parse the String to the required Date using something like SimpleDateFormat
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
} catch (ParseException ex) {
ex.printStackTrace();
}
if (date == null) {
// Invalid date format
} else {
// Valid date format
}
You could then simply write a simple method that performed this action and returned true when ever Date was not null...
As a suggestion...
Updated with running example
I'm not sure what you are doing, but, the following example...
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDateParser {
public static void main(String[] args) {
System.out.println("isValid - dd/MM/yyyy with 20130925 = " + isValidFormat("dd/MM/yyyy", "20130925"));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 = " + isValidFormat("dd/MM/yyyy", "25/09/2013"));
System.out.println("isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = " + isValidFormat("dd/MM/yyyy", "25/09/2013 12:13:50"));
}
public static boolean isValidFormat(String format, String value) {
Date date = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.parse(value);
if (!value.equals(sdf.format(date))) {
date = null;
}
} catch (ParseException ex) {
ex.printStackTrace();
}
return date != null;
}
}
Outputs (something like)...
java.text.ParseException: Unparseable date: "20130925"
isValid - dd/MM/yyyy with 20130925 = false
isValid - dd/MM/yyyy with 25/09/2013 = true
isValid - dd/MM/yyyy with 25/09/2013 12:13:50 = false
at java.text.DateFormat.parse(DateFormat.java:366)
at javaapplication373.JavaApplication373.isValidFormat(JavaApplication373.java:28)
at javaapplication373.JavaApplication373.main(JavaApplication373.java:19)
Not correct. For isValidFormat("yyyy-MM-dd", "2017-18--15"); not throw any Exception.
isValid - yyyy-MM-dd", "2017-18--15 = false
Seems to work as expected for me - the method doesn't rely on (nor does it throw) the exception alone to perform it's operation
For your case, you may use regex:
boolean isValidFormat = input.matches("([0-9]{2})/([0-9]{2})/([0-9]{4})");
For a larger scope or if you want a flexible solution, refer to MadProgrammer's answer.
Edit
Almost 5 years after posting this answer, I realize that this is a stupid way to validate a date format. But i'll just leave this here to tell people that using regex to validate a date is unacceptable
You can try this to simple date format valdation
public Date validateDateFormat(String dateToValdate) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HHmmss");
//To make strict date format validation
formatter.setLenient(false);
Date parsedDate = null;
try {
parsedDate = formatter.parse(dateToValdate);
System.out.println("++validated DATE TIME ++"+formatter.format(parsedDate));
} catch (ParseException e) {
//Handle exception
}
return parsedDate;
}
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
formatter.setLenient(false);
try {
Date date= formatter.parse("02/03/2010");
} catch (ParseException e) {
//If input date is in different format or invalid.
}
formatter.setLenient(false) will enforce strict matching.
If you are using Joda-Time -
private boolean isValidDate(String dateOfBirth) {
boolean valid = true;
try {
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy");
DateTime dob = formatter.parseDateTime(dateOfBirth);
} catch (Exception e) {
valid = false;
}
return valid;
}
Here's a simple method:
public static boolean checkDatePattern(String padrao, String data) {
try {
SimpleDateFormat format = new SimpleDateFormat(padrao, LocaleUtils.DEFAULT_LOCALE);
format.parse(data);
return true;
} catch (ParseException e) {
return false;
}
}
For example, if you want the date format to be "03.11.2017"
if (String.valueOf(DateEdit.getText()).matches("([1-9]{1}|[0]{1}[1-9]{1}|[1]{1}[0-9]{1}|[2]{1}[0-9]{1}|[3]{1}[0-1]{1})" +
"([.]{1})" +
"([0]{1}[1-9]{1}|[1]{1}[0-2]{1}|[1-9]{1})" +
"([.]{1})" +
"([20]{2}[0-9]{2})"))
checkFormat=true;
else
checkFormat=false;
if (!checkFormat) {
Toast.makeText(getApplicationContext(), "incorrect date format! Ex.23.06.2016", Toast.LENGTH_SHORT).show();
}
A combination of the regex and SimpleDateFormat is the right answer i believe. SimpleDateFormat does not catch exception if the individual components are invalid meaning,
Format Defined: yyyy-mm-dd
input: 201-0-12
No exception will be thrown.This case should have been handled.
But with the regex as suggested by Sok Pomaranczowy and Baby will take care of this particular case.
Regex can be used for this with some detailed info for validation, for example this code can be used to validate any date in (DD/MM/yyyy) format with proper date and month value and year between (1950-2050)
public Boolean checkDateformat(String dateToCheck){
String rex="([0]{1}[1-9]{1}|[1-2]{1}[0-9]{1}|[3]{1}[0-1]{1})+
\/([0]{1}[1-9]{1}|[1]{1}[0-2]{2})+
\/([1]{1}[9]{1}[5-9]{1}[0-9]{1}|[2]{1}[0]{1}([0-4]{1}+
[0-9]{1}|[5]{1}[0]{1}))";
return(dateToCheck.matches(rex));
}
I have two strings, the first one contains an actual date, and the second one contains a date format.
I want to compare both the strings. Here is my code:
String s1 = "01/02/2012";
String s2 = "dd/MM/yyyy";
if (s1.equalsIgnoreCase(s2)){
System.out.println("true");}
else {
System.out.println("false");}
I have tried with all the string methods (like compare(), equalTo(), etc.). It's always executing the else part, i.e. the condition is always "false".
Check Using Format
if(isValidDate("01/02/2012")){
System.out.println("true");}else{
System.out.println("false");}
}
public boolean isValidDate(String inDate) {
if (inDate == null)
return false;
// set the format to use as a constructor argument
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
if (inDate.trim().length() != dateFormat.toPattern().length())
return false;
dateFormat.setLenient(false);
try {
// parse the inDate parameter
dateFormat.parse(inDate.trim());
} catch (ParseException pe) {
return false;
}
return true;
}
// date validation using SimpleDateFormat
// it will take a string and make sure it's in the proper
// format as defined by you, and it will also make sure that
// it's a legal date
public boolean isValidDate(String date)
{
// set date format, this can be changed to whatever format
// you want, MM-dd-yyyy, MM.dd.yyyy, dd.MM.yyyy etc.
// you can read more about it here:
// http://java.sun.com/j2se/1.4.2/docs/api/index.html
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
// declare and initialize testDate variable, this is what will hold
// our converted string
Date testDate = null;
// we will now try to parse the string into date form
try
{
testDate = sdf.parse(date);
}
// if the format of the string provided doesn't match the format we
// declared in SimpleDateFormat() we will get an exception
catch (ParseException e)
{
errorMessage = "the date you provided is in an invalid date" +
" format.";
return false;
}
// dateformat.parse will accept any date as long as it's in the format
// you defined, it simply rolls dates over, for example, december 32
// becomes jan 1 and december 0 becomes november 30
// This statement will make sure that once the string
// has been checked for proper formatting that the date is still the
// date that was entered, if it's not, we assume that the date is invalid
if (!sdf.format(testDate).equals(date))
{
errorMessage = "The date that you provided is invalid.";
return false;
}
// if we make it to here without getting an error it is assumed that
// the date was a valid one and that it's in the proper format
return true;
} // end isValidDate
Do it as below:
String s1 = "01/02/2012";
String s2 = "dd/MM/yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(s2);
try {
Date date = simpleDateFormat.parse(s1);
System.out.println(simpleDateFormat.format(date));
System.out.println("Parse successful. s1 matches with s2");
} catch (ParseException e) {
System.out.println("Parse failed. s1 differs by format.");
}
Please Note: a little warning
if you have s1="01/13/2012" parse will get successful, albeit it is not correct, because it will consider it as "01/01/2013" instead. So if you are ok with this, then proceed, else go ahead with your own implementation.
I find it curious that the most obvious way to create Date objects in Java has been deprecated and appears to have been "substituted" with a not so obvious to use lenient calendar.
How do you check that a date, given as a combination of day, month, and year, is a valid date?
For instance, 2008-02-31 (as in yyyy-mm-dd) would be an invalid date.
Key is df.setLenient(false);. This is more than enough for simple cases. If you are looking for a more robust (I doubt that) and/or alternate libraries like joda-time, then look at the answer by user "tardate"
final static String DATE_FORMAT = "dd-MM-yyyy";
public static boolean isDateValid(String date)
{
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
As shown by #Maglob, the basic approach is to test the conversion from string to date using SimpleDateFormat.parse. That will catch invalid day/month combinations like 2008-02-31.
However, in practice that is rarely enough since SimpleDateFormat.parse is exceedingly liberal. There are two behaviours you might be concerned with:
Invalid characters in the date string
Surprisingly, 2008-02-2x will "pass" as a valid date with locale format = "yyyy-MM-dd" for example. Even when isLenient==false.
Years: 2, 3 or 4 digits?
You may also want to enforce 4-digit years rather than allowing the default SimpleDateFormat behaviour (which will interpret "12-02-31" differently depending on whether your format was "yyyy-MM-dd" or "yy-MM-dd")
A Strict Solution with the Standard Library
So a complete string to date test could look like this: a combination of regex match, and then a forced date conversion. The trick with the regex is to make it locale-friendly.
Date parseDate(String maybeDate, String format, boolean lenient) {
Date date = null;
// test date string matches format structure using regex
// - weed out illegal characters and enforce 4-digit year
// - create the regex based on the local format string
String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {
// date string matches format structure,
// - now test it can be converted to a valid date
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
sdf.applyPattern(format);
sdf.setLenient(lenient);
try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
}
return date;
}
// used like this:
Date date = parseDate( "21/5/2009", "d/M/yyyy", false);
Note that the regex assumes the format string contains only day, month, year, and separator characters. Aside from that, format can be in any locale format: "d/MM/yy", "yyyy-MM-dd", and so on. The format string for the current locale could be obtained like this:
Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();
Joda Time - Better Alternative?
I've been hearing about joda time recently and thought I'd compare. Two points:
Seems better at being strict about invalid characters in the date string, unlike SimpleDateFormat
Can't see a way to enforce 4-digit years with it yet (but I guess you could create your own DateTimeFormatter for this purpose)
It's quite simple to use:
import org.joda.time.format.*;
import org.joda.time.DateTime;
org.joda.time.DateTime parseDate(String maybeDate, String format) {
org.joda.time.DateTime date = null;
try {
DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
date = fmt.parseDateTime(maybeDate);
} catch (Exception e) { }
return date;
}
tl;dr
Use the strict mode on java.time.DateTimeFormatter to parse a LocalDate. Trap for the DateTimeParseException.
LocalDate.parse( // Represent a date-only value, without time-of-day and without time zone.
"31/02/2000" , // Input string.
DateTimeFormatter // Define a formatting pattern to match your input string.
.ofPattern ( "dd/MM/uuuu" )
.withResolverStyle ( ResolverStyle.STRICT ) // Specify leniency in tolerating questionable inputs.
)
After parsing, you might check for reasonable value. For example, a birth date within last one hundred years.
birthDate.isAfter( LocalDate.now().minusYears( 100 ) )
Avoid legacy date-time classes
Avoid using the troublesome old date-time classes shipped with the earliest versions of Java. Now supplanted by the java.time classes.
LocalDate & DateTimeFormatter & ResolverStyle
The LocalDate class represents a date-only value without time-of-day and without time zone.
String input = "31/02/2000";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" );
try {
LocalDate ld = LocalDate.parse ( input , f );
System.out.println ( "ld: " + ld );
} catch ( DateTimeParseException e ) {
System.out.println ( "ERROR: " + e );
}
The java.time.DateTimeFormatter class can be set to parse strings with any of three leniency modes defined in the ResolverStyle enum. We insert a line into the above code to try each of the modes.
f = f.withResolverStyle ( ResolverStyle.LENIENT );
The results:
ResolverStyle.LENIENTld: 2000-03-02
ResolverStyle.SMARTld: 2000-02-29
ResolverStyle.STRICTERROR: java.time.format.DateTimeParseException: Text '31/02/2000' could not be parsed: Invalid date 'FEBRUARY 31'
We can see that in ResolverStyle.LENIENT mode, the invalid date is moved forward an equivalent number of days. In ResolverStyle.SMART mode (the default), a logical decision is made to keep the date within the month and going with the last possible day of the month, Feb 29 in a leap year, as there is no 31st day in that month. The ResolverStyle.STRICT mode throws an exception complaining that there is no such date.
All three of these are reasonable depending on your business problem and policies. Sounds like in your case you want the strict mode to reject the invalid date rather than adjust it.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
You can use SimpleDateFormat
For example something like:
boolean isLegalDate(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
return sdf.parse(s, new ParsePosition(0)) != null;
}
The current way is to use the calendar class. It has the setLenient method that will validate the date and throw and exception if it is out of range as in your example.
Forgot to add:
If you get a calendar instance and set the time using your date, this is how you get the validation.
Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
cal.getTime();
}
catch (Exception e) {
System.out.println("Invalid date");
}
java.time
With the Date and Time API (java.time classes) built into Java 8 and later, you can use the LocalDate class.
public static boolean isDateValid(int year, int month, int day) {
try {
LocalDate.of(year, month, day);
} catch (DateTimeException e) {
return false;
}
return true;
}
Building on Aravind's answer to fix the problem pointed out by ceklock in his comment, I added a method to verify that the dateString doesn't contain any invalid character.
Here is how I do:
private boolean isDateCorrect(String dateString) {
try {
Date date = mDateFormatter.parse(dateString);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return matchesOurDatePattern(dateString); //added my method
}
catch (ParseException e) {
return false;
}
}
/**
* This will check if the provided string matches our date format
* #param dateString
* #return true if the passed string matches format 2014-1-15 (YYYY-MM-dd)
*/
private boolean matchesDatePattern(String dateString) {
return dateString.matches("^\\d+\\-\\d+\\-\\d+");
}
An alternative strict solution using the standard library is to perform the following:
1) Create a strict SimpleDateFormat using your pattern
2) Attempt to parse the user entered value using the format object
3) If successful, reformat the Date resulting from (2) using the same date format (from (1))
4) Compare the reformatted date against the original, user-entered value. If they're equal then the value entered strictly matches your pattern.
This way, you don't need to create complex regular expressions - in my case I needed to support all of SimpleDateFormat's pattern syntax, rather than be limited to certain types like just days, months and years.
I suggest you to use org.apache.commons.validator.GenericValidator class from apache.
GenericValidator.isDate(String value, String datePattern, boolean strict);
Note: strict - Whether or not to have an exact match of the datePattern.
I think the simpliest is just to convert a string into a date object and convert it back to a string. The given date string is fine if both strings still match.
public boolean isDateValid(String dateString, String pattern)
{
try
{
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
if (sdf.format(sdf.parse(dateString)).equals(dateString))
return true;
}
catch (ParseException pe) {}
return false;
}
Assuming that both of those are Strings (otherwise they'd already be valid Dates), here's one way:
package cruft;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateValidator
{
private static final DateFormat DEFAULT_FORMATTER;
static
{
DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
DEFAULT_FORMATTER.setLenient(false);
}
public static void main(String[] args)
{
for (String dateString : args)
{
try
{
System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
}
catch (ParseException e)
{
System.out.println("could not parse " + dateString);
}
}
}
public static Date convertDateString(String dateString) throws ParseException
{
return DEFAULT_FORMATTER.parse(dateString);
}
}
Here's the output I get:
java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011
Process finished with exit code 0
As you can see, it does handle both of your cases nicely.
This is working great for me. Approach suggested above by Ben.
private static boolean isDateValid(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
Date d = asDate(s);
if (sdf.format(d).equals(s)) {
return true;
} else {
return false;
}
} catch (ParseException e) {
return false;
}
}
looks like SimpleDateFormat is not checking the pattern strictly even after setLenient(false); method is applied on it, so i have used below method to validate if the date inputted is valid date or not as per supplied pattern.
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public boolean isValidFormat(String dateString, String pattern) {
boolean valid = true;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
try {
formatter.parse(dateString);
} catch (DateTimeParseException e) {
valid = false;
}
return valid;
}
Two comments on the use of SimpleDateFormat.
it should be declared as a static instance
if declared as static access should be synchronized as it is not thread safe
IME that is better that instantiating an instance for each parse of a date.
Above methods of date parsing are nice , i just added new check in existing methods that double check the converted date with original date using formater, so it works for almost each case as i verified. e.g. 02/29/2013 is invalid date.
Given function parse the date according to current acceptable date formats. It returns true if date is not parsed successfully.
public final boolean validateDateFormat(final String date) {
String[] formatStrings = {"MM/dd/yyyy"};
boolean isInvalidFormat = false;
Date dateObj;
for (String formatString : formatStrings) {
try {
SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
sdf.applyPattern(formatString);
sdf.setLenient(false);
dateObj = sdf.parse(date);
System.out.println(dateObj);
if (date.equals(sdf.format(dateObj))) {
isInvalidFormat = false;
break;
}
} catch (ParseException e) {
isInvalidFormat = true;
}
}
return isInvalidFormat;
}
Here's what I did for Node environment using no external libraries:
Date.prototype.yyyymmdd = function() {
var yyyy = this.getFullYear().toString();
var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
var dd = this.getDate().toString();
return zeroPad([yyyy, mm, dd].join('-'));
};
function zeroPad(date_string) {
var dt = date_string.split('-');
return dt[0] + '-' + (dt[1][1]?dt[1]:"0"+dt[1][0]) + '-' + (dt[2][1]?dt[2]:"0"+dt[2][0]);
}
function isDateCorrect(in_string) {
if (!matchesDatePattern) return false;
in_string = zeroPad(in_string);
try {
var idate = new Date(in_string);
var out_string = idate.yyyymmdd();
return in_string == out_string;
} catch(err) {
return false;
}
function matchesDatePattern(date_string) {
var dateFormat = /[0-9]+-[0-9]+-[0-9]+/;
return dateFormat.test(date_string);
}
}
And here is how to use it:
isDateCorrect('2014-02-23')
true
// to return valid days of month, according to month and year
int returnDaysofMonth(int month, int year) {
int daysInMonth;
boolean leapYear;
leapYear = checkLeap(year);
if (month == 4 || month == 6 || month == 9 || month == 11)
daysInMonth = 30;
else if (month == 2)
daysInMonth = (leapYear) ? 29 : 28;
else
daysInMonth = 31;
return daysInMonth;
}
// to check a year is leap or not
private boolean checkLeap(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
Here is I would check the date format:
public static boolean checkFormat(String dateTimeString) {
return dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}") || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")
|| dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}") || dateTimeString
.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") ||
dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}Z");
}
public static String detectDateFormat(String inputDate, String requiredFormat) {
String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
String dateFormat;
if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
dateFormat = "MMddyyyy";
} else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
dateFormat = "ddMMyyyy";
} else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
dateFormat = "yyyyMMdd";
} else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
dateFormat = "yyyyddMM";
} else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
dateFormat = "ddMMMyyyy";
} else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
dateFormat = "MMMddyyyy";
} else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
dateFormat = "yyyyMMMdd";
} else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
dateFormat = "yyyyddMMM";
} else {
return "Pattern Not Added";
//add your required regex
}
try {
String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));
return formattedDate;
} catch (Exception e) {
//
return "";
}
}
setLenient to false if you like a strict validation
public boolean isThisDateValid(String dateToValidate, String dateFromat){
if(dateToValidate == null){
return false;
}
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);
try {
//if not valid, it will throw ParseException
Date date = sdf.parse(dateToValidate);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
return false;
}
return true;
}
With 'legacy' date format, we can format the result and compare it back to the source.
public boolean isValidFormat(String source, String pattern) {
SimpleDateFormat sd = new SimpleDateFormat(pattern);
sd.setLenient(false);
try {
Date date = sd.parse(source);
return date != null && sd.format(date).equals(source);
} catch (Exception e) {
return false;
}
}
This execerpt says 'false' to source=01.01.04 with pattern '01.01.2004'
We can use the org.apache.commons.validator.GenericValidator's method directly without adding the whole library:
public static boolean isValidDate(String value, String datePattern, boolean strict) {
if (value == null
|| datePattern == null
|| datePattern.length() <= 0) {
return false;
}
SimpleDateFormat formatter = new SimpleDateFormat(datePattern, Locale.ENGLISH);
formatter.setLenient(false);
try {
formatter.parse(value);
} catch(ParseException e) {
return false;
}
if (strict && (datePattern.length() != value.length())) {
return false;
}
return true;
}
A simple and elegant way for Android developers (Java 8 not required):
// month value is 1-based. e.g., 1 for January.
public static boolean isDateValid(int year, int month, int day) {
Calendar calendar = Calendar.getInstance();
try {
calendar.setLenient(false);
calendar.set(year, month-1, day);
calendar.getTime();
return true;
} catch (Exception e) {
return false;
}
}
Below code works with dd/MM/yyyy format and can be used to check NotNull,NotEmpty as well.
public static boolean validateJavaDate(String strDate) {
if (strDate != null && !strDate.isEmpty() && !strDate.equalsIgnoreCase(" ")) {
{
SimpleDateFormat date = new SimpleDateFormat("dd/MM/yyyy");
date.setLenient(false);
try {
Date javaDate = date.parse(strDate);
System.out.println(strDate + " Valid Date format");
}
catch (ParseException e) {
System.out.println(strDate + " Invalid Date format");
return false;
}
return true;
}
} else {
System.out.println(strDate + "----> Date is Null/Empty");
return false;
}
}