I have method that can take 2 different types of date formats:
Credit card
expiration date is considered expired on the last day of that month. So, if cc date is May, 2017 (05/17), this cc is considered expired on 31th of May.
Funding expiration date will expire on the day it says it expires. So, if I am looking at it on the same day, it should return TRUE as funding has expired.
This is my code:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public static boolean dateHasExpired(String dateInput)
{
LocalDate d = LocalDate.now();
LocalDate dateParsed = null;
if (dateInput.contains("/"))
{
int iYear = Integer.parseInt(dateInput.substring(dateInput.indexOf("/") + 1));
int iMonth = Integer.parseInt(dateInput.substring(0, dateInput.indexOf("/")));
int daysInMonth = LocalDate.of(iYear, iMonth, 1).getMonth().maxLength();
dateInput = iMonth+"/"+daysInMonth+"/"+iYear;
}
else
{
dateInput = ConvertDate(dateInput, "yyyyMMdd", "MM/dd/yyyy");
}
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
dateParsed = LocalDate.parse(dateInput, dateTimeFormatter);
return d.compareTo(dateParsed) <= 0;
}
public static String ConvertDate(String dateValue, String currentFormat, String requiredFormat)
{
SimpleDateFormat inFormatter = new SimpleDateFormat(currentFormat);
SimpleDateFormat outFormatter = new SimpleDateFormat(requiredFormat);
String outDate = "";
try
{
java.util.Date date = inFormatter.parse(dateValue);
outDate = outFormatter.format(date);
}
catch (ParseException e) {
ErrorLogger.logError ( e );
}
return outDate;
}
Does anyone know of better way of doing this?
I also noticed LocalDate
doesn't account for Leap Year
, so Feb 2015 has 29 days, just like Feb 2016, so my daysInMonth
will not be a good number.
Looks like Date is more tollerant than LocalDate when it comes to year being yy and month 5 for month of May.
You can use java.time.YearMonth
class, which contains a method that returns the last day of the respective month (and also takes care of leap years):
public static boolean dateHasExpired(String dateInput) {
LocalDate today = LocalDate.now();
LocalDate dateParsed = null;
if (dateInput.contains("/")) {
// parse credit card expiration date
YearMonth ym = YearMonth.parse(dateInput, DateTimeFormatter.ofPattern("MM/yy"));
// get last day of month (taking care of leap years)
dateParsed = ym.atEndOfMonth();
} else {
// parse funding expiration date
dateParsed = LocalDate.parse(dateInput, DateTimeFormatter.ofPattern("yyyyMMdd"));
}
// expired if today is equals or after dateParsed
return ! today.isBefore(dateParsed);
}
With this code (considering that today is May 02, 2017):
System.out.println(dateHasExpired("04/17")); // true
System.out.println(dateHasExpired("05/17")); // false
System.out.println(dateHasExpired("06/17")); // false
System.out.println(dateHasExpired("20170501")); //true
System.out.println(dateHasExpired("20170502")); // true
System.out.println(dateHasExpired("20170503")); // false
Note that atEndOfMonth()
method takes care of leap years, so these will also work:
System.out.println(dateHasExpired("02/15"));
System.out.println(dateHasExpired("02/16"));
I've added a System.out.println(dateParsed);
in dateHasExpired
method, just to check if the date is being parsed correctly. And the output for the dates above are (respectively):
2015-02-28
2016-02-29
And dateHasExpired
returns true
for both, as expected.