PHP DateTime信用卡到期

rmbxnbpk  于 2022-11-21  发布在  PHP
关注(0)|答案(8)|浏览(209)

我试图使用日期时间来检查信用卡的有效期是否已过期,但我有点迷路了。
我只想比较mm/yy日期。
这是我目前为止的代码

$expmonth = $_POST['expMonth']; //e.g 08
$expyear = $_POST['expYear']; //e.g 15

$rawExpiry = $expmonth . $expyear;

$expiryDateTime = \DateTime::createFromFormat('my', $rawExpiry);
$expiryDate = $expiryDateTime->format('m y');

$currentDateTime = new \DateTime();
$currentDate = $currentDateTime->format('m y');

if ($expiryDate < $currentDate) {
    echo 'Expired';
} else {
    echo 'Valid';
}

我感觉我快到了,但是if语句产生了不正确的结果。任何帮助都将不胜感激。

zaq34kh6

zaq34kh61#

这比你想象的要简单。你要处理的数据的格式并不重要,因为PHP会在内部进行比较。

$expires = \DateTime::createFromFormat('my', $_POST['expMonth'].$_POST['expYear']);
$now     = new \DateTime();

if ($expires < $now) {
    // expired
}
tez616oj

tez616oj2#

您可以使用DateTime class来产生DateTime对象,该对象与使用DateTime::createFromFormat()建构函式的指定日期字串格式相符。
格式('my')将匹配任何具有字符串模式'mmyy'的日期字符串,例如'0620'。或者,对于具有4位数年份的日期,使用格式'mY',该格式将匹配具有以下字符串模式'mmyyyy'的日期,例如'062020'。使用DateTimeZone类指定时区也是明智的。

$expiryMonth = 06;
$expiryYear = 20;
$timezone = new DateTimeZone('Europe/London');
$expiryTime = \DateTime::createFromFormat('my', $expiryMonth.$expiryYear, $timezone);

请参阅DateTime::createFromFormat页面了解更多格式。
但是,对于信用卡/借记卡到期日,您还需要考虑完整的到期日期和时间-而不仅仅是月份和年份。
如果没有指定,DateTime::createFromFormat将默认使用一个月中的今天(例如17)。这意味着信用卡可能会在还有几天到期时显示为过期。如果信用卡在06/20到期(例如2020年6月),那么它实际上在2020年7月1日00:00:00停止工作。modify方法修复了这个问题。例如:

$expiryTime = \DateTime::createFromFormat('my', $expiryMonth.$expiryYear, $timezone)->modify('+1 month first day of midnight');

字符串'+1 month first day of midnight'有三个作用。

  • “+1个月”-增加一个月。
  • 'first day of' -切换到该月的第一天
  • '午夜' -将时间更改为00:00:00

modify方法对于许多日期操作确实很有用!
因此,为了回答这个问题,您需要对格式进行轻微调整,以适应个位数月份:

$expiryMonth = 6;
$expiryYear = 20;
$timezone = new DateTimeZone('Europe/London');
$expiryTime = \DateTime::createFromFormat(
  'm-y',
   $expiryMonth.'-'.$expiryYear,
   $timezone
)->modify('+1 month first day of midnight');

$currentTime = new \DateTime('now', $timezone);

if ($expiryTime < $currentTime) {
    // Card has expired.
}
ctzwtxfj

ctzwtxfj3#

对上述答案的补充。请注意,默认情况下,天数也将包含在计算中。例如,today为2019-10-31,如果运行以下命令:

\DateTime::createFromFormat('Ym', '202111');

它将输出2021-12-01,因为第31天在十一月中不存在,它将向DateTime对象多添加1天,副作用是您将处于十二月而不是预期的十一月。
我的建议是在代码中始终使用day。

yiytaume

yiytaume4#

对于op的问题:

$y=15;
$m=05;

if(strtotime( substr(date('Y'), 0, 2)."{$y}-{$m}" ) < strtotime( date("Y-m")  ))
{
  echo 'card is expired';
}

对于满一年的其他人:

$y=2015;
$m=5;

if(strtotime("{$y}-{$m}") < strtotime( date("Y-m")  ))
{
  echo 'card is expired';
}
cuxqih21

cuxqih215#

将字符串“201709”与当前的年-月进行比较不是更简单吗?我想,创建datetime对象将花费php一些精力。

if($_POST['expYear']. str_pad($_POST['expMonth'],2,'0', STR_PAD_LEFT ) < date('Ym')) {
   echo 'expired';

}

亚当说

hjqgdpho

hjqgdpho6#

best answer是由John孔德提供的,它只做最少的处理:创建两个正确的DateTime对象,比较它们,这就是它所需要的。
它也可以工作,因为你开始,但你必须格式化日期的方式,把年份放在第一位。
想一想:作为日期,08/15(August 2015)在12/14(December 2014)之后,但作为字符串,'08 15''12 14'之前。
当年份在前时,即使是字符串,也会先比较年份,然后再比较,只有当年份相等时,才会比较月份:

$expiryDate  = $expiryDateTime->format('y m');
$currentDate = $currentDateTime->format('y m');

if ($expiryDate < $currentDate) {
    echo 'Expired';
} else {
    echo 'Valid';
}
z9smfwbn

z9smfwbn7#

保持简单,就像我上面的答案说,除了你需要字符串垫到左边:

isCardExpired($month, $year)
{
    $expires = $year.str_pad($month, 2, '0', STR_PAD_LEFT);
    $now = date('Ym');

    return $expires < $now;
}

无需使用DateTime添加额外的PHP负载

fdbelqdn

fdbelqdn8#

如果您使用的是Carbon,这是一个非常流行的Datetime扩展库,那么它应该是:

$expMonth = $_POST['month'];
$expYear = $_POST['year'];
$format_m_y = str_pad($expMonth,2,'0', STR_PAD_LEFT).'-'.substr($expYear, 2);

$date = \Carbon\Carbon::createFromFormat('m-y', $format_m_y)
         ->endOfMonth()
         ->startOfDay();

if ($date->isPast()) {
  // this card is expired
}

还要考虑确切的到期日期和时间:
信用卡在印成到期日的月底到期,而不是在月初。许多卡实际上在技术上是在该月底后的一天到期。在任何情况下,除非它们列出了具体的到期日沿着月份和年份,持卡人不应等到最后一刻才换卡。Source

相关问题