So I'm trying to create an if else statement where if a date from the jdatechooser is before today's date, then an error message would occur. From my knowledge, you can get today's date as LocalDate.now(), format it into a string, and then do a try-catch to parse it back into a Date. For the jdatechooser, you can grab that as a Date, format it into a string, and then do a try-catch to parse it back into a date as well. The only issue with this is when you do jdate.before(localdate) an error occurs. Is there another method of doing this? I saw that you could get today's date as an Instance, but I don't have much experience with that yet.
This is the code that I tried:
try {
//Checks to see if New Due Date is a date set before today's date
//Grabs today's date, converts it into string, then converts it into date
LocalDate ld = LocalDate.now();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy");
String tds = sdf.format(ld);
Date tdd = sdf.parse(tds);
//Grabs reactivateDateChooser1, converts it into string, then converts it into date
Date rdc = reactivateDateChooser1.getDate();
SimpleDateFormat sdf1 = new SimpleDateFormat("MMM dd, yyyy");
String rdcs = sdf1.format(rdc);
Date rdcd = sdf1.parse(rdcs);
//If the new Due Date is before or on today's date, then error message will show
if(rdcd.before(tdd)){
JOptionPane.showMessageDialog(null, "Please select a date after " + tds, "Select Valid Date", JOptionPane.ERROR_MESSAGE);
}
//If the date chooser is empty, then error message will show
else if (reactivateDateChooser1.getDate() == null){
JOptionPane.showMessageDialog(null, "Please select a date", "Needs Date", JOptionPane.ERROR_MESSAGE);
}
//Otherwise, if the new date is after today's date, then the function will happen
else if (rdcd.after(tdd)){
changeStatusToActive();
statusCheck1.setText("");
refreshClassTable();
closeReactivateDialog();
}
} catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
And this is the error that I'm getting:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.ITALY);
//Checks to see if New Due Date is a date set before today's date
//Grabs today's date
LocalDate today = LocalDate.now();
//Grabs reactivateDateChooser1, converts it into LocalDate (if not null)
Date reactivateUtilDate = reactivateDateChooser1.getDate();
//If the date chooser is empty, then error message will show
if (reactivateUtilDate == null) {
JOptionPane.showMessageDialog(null, "Please select a date",
"Needs Date", JOptionPane.ERROR_MESSAGE);
} else {
LocalDate reactivateDate = reactivateUtilDate.toInstant()
.atZone(ZoneId.of("Asia/Singapore"))
.toLocalDate();
//If the new Due Date is before or on today's date, then error message will show
//Otherwise, if the new date is after today's date, then the function will happen
if (reactivateDate.isAfter(today)) {
changeStatusToActive();
statusCheck1.setText("");
refreshClassTable();
closeReactivateDialog();
} else {
String todayString = today.format(dateFormatter);
JOptionPane.showMessageDialog(null,
"Please select a date after " + todayString,
"Select Valid Date", JOptionPane.ERROR_MESSAGE);
}
}
Rather than converting from the modern LocalDate
to the outmoded Date
, better to use the modern and better API as much as possible. I know you cannot avoid getting a java.util.Date
from your JDateChooser
, so first thing convert it to the modern Instant
type and do further conversions from there to obtain a LocalDate
that you can compare with the one you have. LocalDate
has methods isBefore
and isAfter
for comparing to other LocalDate
objects.
The old date and time classes Date
, SimpleDateFormat
and friends have proven to be poorly designed, and SimpleDateFormat
in particular is notoriously troublesome. Just look at how many questions there are on Stack Overflow about surprising and unwanted behaviour of SimpleDateFormat
. All of this is why Oracle issued java.time
in 2014 as a replacement. And surely, the modern API is so much nicer to work with. I recommend it warmly.
I further recommend you specify locale for your formatter (even if you just specify Locale.getDefault()
) and time zone for your conversion from Date
to LocalDate
(even if you go for ZoneId.systemDefault()
. So no one needs to be in doubt that a locale and a time zone are used and you have chosen them consciously. Finally I have made an attempt at more explanatory variable names.