Reputation: 61
i need to validate user input as valid date. User can enter dd/mm/yyyy or mm/yyyy (both are valid)
to validate this i was doing
try{
GregorianCalendar cal = new GregorianCalendar();
cal.setLenient(false);
String []userDate = uDate.split("/");
if(userDate.length == 3){
cal.set(Calendar.YEAR, Integer.parseInt(userDate[2]));
cal.set(Calendar.MONTH, Integer.parseInt(userDate[1]));
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(userDate[0]));
cal.getTime();
}else if(userDate.length == 2){
cal.set(Calendar.YEAR, Integer.parseInt(userDate[1]));
cal.set(Calendar.MONTH, Integer.parseInt(userDate[0]));
cal.getTime();
}else{
// invalid date
}
}catch(Exception e){
//Invalid date
}
as GregorianCalendar start month with 0, 30/01/2009 or 12/2009 gives error.
any suggestion how to solve this issue.
Upvotes: 6
Views: 13783
Reputation: 338326
Use a try - catch
to trap DateTimeParseException
thrown from LocalDate.parse
and YearMonth.parse
in the java.time classes.
The modern approach uses the java.time classes.
YearMonth
For only a year-month without a day-of-month, use the YearMonth
class.
If possible, have your users use standard ISO 8601 format for data entry: YYYY-MM
. The java.time classes use the standard formats by default when parsing/generating strings.
YearMonth ym = YearMonth.parse( "2018-01" ) ;
If not possible, specify a formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ;
YearMonth ym = YearMonth.parse( "01/2018" , f ) ;
To test for invalid input, trap for an exception.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/uuuu" ) ;
YearMonth ym = null ;
try{
ym = YearMonth.parse( "01/2018" , f ) ;
} catch ( DateTimeParseException e ) {
// Handle faulty input
…
}
LocalDate
For a date-only value, without a time-of-day and without a time zone, use LocalDate
class.
Again, use standard ISO 8601 format for data-entry if possible: YYYY-MM-DD
.
LocalDate ld = LocalDate.parse( "2018-01-23" ) ;
If not, specify a formatting pattern and trap for exception as seen above.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = null ;
try{
ld = LocalDate.parse( "23/01/2018" , f ) ;
} catch ( DateTimeParseException e ) {
// Handle faulty input
…
}
If the input may be either a date-only or a year-month, then test the length of input to determine which is which.
int length = input.length() ;
switch ( length ) {
case 7 :
… // Process as year-month using code seen above.
case 10 :
… // Process as date-only using code seen above.
default:
… // ERROR, unexpected input.
}
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
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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?
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.
Upvotes: 1
Reputation: 240870
Use SimpleDateFormat
to validate Date
and setLenient
to false
.
Upvotes: 3
Reputation: 43504
Use SimpleDateformat
. If the parsing failes it throws a ParseException
:
private Date getDate(String text) throws java.text.ParseException {
try {
// try the day format first
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setLenient(false);
return df.parse(text);
} catch (ParseException e) {
// fall back on the month format
SimpleDateFormat df = new SimpleDateFormat("MM/yyyy");
df.setLenient(false);
return df.parse(text);
}
}
Upvotes: 10