【问题标题】:validate the credit card expiry date using java?使用java验证信用卡到期日期?
【发布时间】:2012-07-16 18:07:28
【问题描述】:

我希望以 MM/YY 格式验证信用卡到期日期。我不知道如何验证,是否选择简单日期格式/正则表达式。

感谢您的帮助。

【问题讨论】:

  • 您是在询问匹配 MM/YY 格式的正则表达式,还是询问在这种情况下使用正则表达式是否是个好主意?

标签: java regex validation date


【解决方案1】:

使用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

【讨论】:

  • 为了安全起见,您需要明确设置时间(例如 00:00 ... 等)以避免在极端情况下失败
  • 问题是如果你不使用SimpleDateFormat.setLenient(false),“42701/13”仍然会验证,“1/13”也会验证,这不是我的卡的样子喜欢!
  • 效果很好。我使用了 parse 函数,但从不使用 setLenient(false) 属性,所以它从来没有工作过
  • 我使用相同的代码来检查到期,但如果我们超过 34 的任何一年,例如 01/35、01/41 等,到期结果为真。解析方法将“01/41”更改为 01/1941。你们有过这种经历吗?
  • @amique 默认切换日期为 1935 年,但您可以将其设置为更适合您的其他日期:请参阅 SimpleDateFormat#get2DigitYearStart()SimpleDateFormat#set2DigitYearStart(Date)
【解决方案2】:

你真的需要使用正则表达式吗?正则表达式实际上只适合匹配字符,而不是日期。我认为只使用简单的日期函数会容易得多。

【讨论】:

  • 好的,谢谢。这就是为什么我很困惑并决定问这个问题。
【解决方案3】:

扮演魔鬼的拥护者......

boolean validateCardExpiryDate(String expiryDate) {
    return expiryDate.matches("(?:0[1-9]|1[0-2])/[0-9]{2}");
}

翻译为:

...所以这个版本需要零填充月份 (01 - 12)。在第一个 0 之后添加 ? 以防止这种情况发生。

【讨论】:

  • 你在哪里检查日期是过去还是未来,你只是检查这是否是有效的数字年份和月份
  • 这是真的!啊,但是 01/19 代表什么世纪? :) 关键是,在某些时候,您必须通过实际使用支付提供商来验证卡详细信息是否正确。这足以验证到期日期是否采用正确的格式 - 客户可能已正确输入它们,它们将适合适当的数据库列等。我想这将是足以满足大多数需求。
  • 对于 Kotlin,您将需要 expires.matches("(?:0[1-9]|1[0-2])/[0-9]{2}".toRegex())
【解决方案4】:

我认为代码会更好:

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());

您需要计算下个月,因为信用卡上显示的月份是卡有效的最后一个月。

【讨论】:

  • 2019年请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API 和它的DateTimeFormatter 中做得更好。
【解决方案5】:

java.time

验证您是否有一个有效的到期日期字符串:

    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。

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多