【发布时间】:2012-07-16 18:07:28
【问题描述】:
我希望以 MM/YY 格式验证信用卡到期日期。我不知道如何验证,是否选择简单日期格式/正则表达式。
感谢您的帮助。
【问题讨论】:
-
您是在询问匹配 MM/YY 格式的正则表达式,还是询问在这种情况下使用正则表达式是否是个好主意?
标签: java regex validation date
我希望以 MM/YY 格式验证信用卡到期日期。我不知道如何验证,是否选择简单日期格式/正则表达式。
感谢您的帮助。
【问题讨论】:
标签: java regex validation date
使用SimpleDateFormat解析Date,然后将其与新的Date进行比较,即“现在”:
String input = "11/12"; // for example
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/yy");
simpleDateFormat.setLenient(false);
Date expiry = simpleDateFormat.parse(input);
boolean expired = expiry.before(new Date());
感谢@ryanp 的宽大处理。如果输入不正确,上面的代码现在将抛出ParseException。
【讨论】:
SimpleDateFormat.setLenient(false),“42701/13”仍然会验证,“1/13”也会验证,这不是我的卡的样子喜欢!
SimpleDateFormat#get2DigitYearStart() 和 SimpleDateFormat#set2DigitYearStart(Date)
你真的需要使用正则表达式吗?正则表达式实际上只适合匹配字符,而不是日期。我认为只使用简单的日期函数会容易得多。
【讨论】:
扮演魔鬼的拥护者......
boolean validateCardExpiryDate(String expiryDate) {
return expiryDate.matches("(?:0[1-9]|1[0-2])/[0-9]{2}");
}
翻译为:
...所以这个版本需要零填充月份 (01 - 12)。在第一个 0 之后添加 ? 以防止这种情况发生。
【讨论】:
我认为代码会更好:
int month = 11;
int year = 2012;
int totalMonth = (year * 12) + month;
totalMonth++; // next month needed
int nextMonth = totalMonth % 12;
int yearOfNextMonth = totalMonth / 12;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/yyyy");
simpleDateFormat.setLenient(false);
Date expiry = simpleDateFormat.parse(nextMonth + "/" + yearOfNextMonth);
boolean expired = expiry.before(new Date());
您需要计算下个月,因为信用卡上显示的月份是卡有效的最后一个月。
【讨论】:
SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API 和它的DateTimeFormatter 中做得更好。
验证您是否有一个有效的到期日期字符串:
DateTimeFormatter ccMonthFormatter = DateTimeFormatter.ofPattern("MM/uu");
String creditCardExpiryDateString = "11/21";
try {
YearMonth lastValidMonth = YearMonth.parse(creditCardExpiryDateString, ccMonthFormatter);
} catch (DateTimeParseException dtpe) {
System.out.println("Not a valid expiry date: " + creditCardExpiryDateString);
}
验证它是否表示信用卡过期:
if (YearMonth.now(ZoneId.systemDefault()).isAfter(lastValidMonth)) {
System.out.println("Credit card has expired");
}
考虑一下您要使用哪个时区,因为新月并非在所有时区的同一时刻开始。如果你想要 UTC:
if (YearMonth.now(ZoneOffset.UTC).isAfter(lastValidMonth)) {
如果您愿意,例如欧洲/基辅时区:
if (YearMonth.now(ZoneId.of("Europe/Kiev")).isAfter(lastValidMonth)) {
链接: Oracle tutorial: Date Time 解释如何使用 java.time。
【讨论】: