【问题标题】:Trouble Comparing Dates in PHP [duplicate]在 PHP 中比较日期时遇到问题 [重复]
【发布时间】:2018-02-19 03:54:56
【问题描述】:

下面的 php 代码会将所有日期显示为过去,除了当前日期。我最初认为它只是检查第一个数字,因此在天数列中放置 2 而不是 9 会产生超过 20 的每一天作为“今天”的一天,但是这并没有发生。

http://sandbox.onlinephpfunctions.com/code/fae07419c11f38454de9f3d301cfd1b87816ff82

<?php
$today = date('2018-02-9');
$ym = date('Y-m');
$day_count = date('t');

for ( $day = 1; $day <= $day_count; $day++) {

$date = $ym.'-'.$day;

if ($today == $date) {
    echo "today \r\n";
    echo $date. "\r\n";
    echo $today. "\r\n";
} elseif ($today > $date) {
    echo "PAST \r\n";
     echo $date. "\r\n";
    echo $today. "\r\n";
} else {
    echo "FUTURE \r\n";
     echo $date. "\r\n";
    echo $today. "\r\n";
  }


}

【问题讨论】:

  • 你到底想做什么?
  • 为什么要处理格式奇怪的日期?为什么不先解决这个问题?

标签: php date calendar comparison


【解决方案1】:

date() 返回string,因此您的比较是字符串比较,而不是数字(或日期)比较。如果你仔细看,你会注意到$today 在当天缺少一个前导零,所以比较出乎意料地工作(记住,这是一个字符串比较)。例如:

$d1 = "2018-02-9";
$d2 = "2018-02-10";
var_dump($d1 > $d2); // true

$d1 = "2018-02-09";
$d2 = "2018-02-10";
var_dump($d1 > $d2); // false

因为,比较到第一个字符串中的 9 并评估为大于第二个字符串中的 1。

您可以通过在 9 之前添加 0 并保留字符串比较(这仍然会产生意外结果)来修复它,或者将日期转换为时间戳并进行适当的数字比较:

<?php
$today = strtotime(date('2018-02-09'));
$ym = strtotime(date('Y-m'));
$day_count = date('t');

for ( $day = 1; $day <= $day_count; $day++) {
    $date = strtotime(date($ym.'-'.$day));
    if ($today == $date) {
        echo "today \r\n";
        echo $date. "\r\n";
        echo $today. "\r\n";
    } elseif ($today > $date) {
        echo "PAST \r\n";
        echo $date. "\r\n";
        echo $today. "\r\n";
    } else {
        echo "FUTURE \r\n";
        echo $date. "\r\n";
        echo $today. "\r\n";
    }
}

Demo

【讨论】:

    【解决方案2】:

    如果您只需确保所有日期都采用Y-m-d 格式,则无需费心将所有日期转换为时间戳。

    代码:(Demo)

    $today = date('2018-02-09');  // fix your input value to be the standard Y-m-d format
    $ym = date('Y-m');
    $day_count = date('t');
    
    for ( $day = 1; $day <= $day_count; ++$day ) {
        $date = $ym.'-'.str_pad($day,2,"0",STR_PAD_LEFT);  // just padd the incremented day variable
        if ($today > $date) {
            echo "PAST ";
        } elseif ($today < $date) {
            echo "FUTURE";
        } else {
            echo "TODAY";
        }
        echo " $date & $today\n";
    }
    

    输出:

    PAST  2018-02-01 & 2018-02-09
    PAST  2018-02-02 & 2018-02-09
    PAST  2018-02-03 & 2018-02-09
    PAST  2018-02-04 & 2018-02-09
    PAST  2018-02-05 & 2018-02-09
    PAST  2018-02-06 & 2018-02-09
    PAST  2018-02-07 & 2018-02-09
    PAST  2018-02-08 & 2018-02-09
    TODAY 2018-02-09 & 2018-02-09
    FUTURE 2018-02-10 & 2018-02-09
    FUTURE 2018-02-11 & 2018-02-09
    FUTURE 2018-02-12 & 2018-02-09
    FUTURE 2018-02-13 & 2018-02-09
    FUTURE 2018-02-14 & 2018-02-09
    FUTURE 2018-02-15 & 2018-02-09
    FUTURE 2018-02-16 & 2018-02-09
    FUTURE 2018-02-17 & 2018-02-09
    FUTURE 2018-02-18 & 2018-02-09
    FUTURE 2018-02-19 & 2018-02-09
    FUTURE 2018-02-20 & 2018-02-09
    FUTURE 2018-02-21 & 2018-02-09
    FUTURE 2018-02-22 & 2018-02-09
    FUTURE 2018-02-23 & 2018-02-09
    FUTURE 2018-02-24 & 2018-02-09
    FUTURE 2018-02-25 & 2018-02-09
    FUTURE 2018-02-26 & 2018-02-09
    FUTURE 2018-02-27 & 2018-02-09
    FUTURE 2018-02-28 & 2018-02-09
    

    【讨论】:

    • 但是这个任务过于复杂了。为这些简单的比较适当地准备数据是很有意义的。
    【解决方案3】:

    您遇到了日期格式问题。您正在比较没有前导零的天数:“2018-02-9”和前导零的天数:“2018-02-09”。

    因此,由于您只是将第一个数字与“9”进行比较,因此每个日期都将小于 9,但 9 除外,它将匹配。当你比较“20”时,比较的不是“20”而是“2”,它返回一个PAST的结果。

    您想要在这里做的是协调您的日期格式。在代码中使用日期时,一个好的最佳实践是在日期中精确地使用前导零来避免这个问题。如果您得到一位数输入,您可以使用 strtotime 函数转换为两位数

    有比您在此处使用的连接循环更好的方法来增加天数(请参阅here 示例),但我不想用额外的代码混淆您,因为我希望您能够看到区别很明显。 正如您在下面看到的,我所做的只是将您的初始第一个日期更改为带有前导零的两位数格式,然后使用strtotime 将您的比较日期也更改为前导零格式:

    <?php
    $today = date('2018-02-09');
    $ym = date('Y-m');
    $day_count = date('d');
    
    for ( $day = 01; $day <= $day_count; $day++) {
    
        $date = date('Y-m-d', strtotime($ym.'-'.$day));
    
        if ($today == $date) {
            echo "today \r\n";
            echo $date. "\r\n";
            echo $today. "\r\n";
        } elseif ($today > $date) {
            echo "PAST \r\n";
            echo $date. "\r\n";
            echo $today. "\r\n";
        } else {
            echo "FUTURE \r\n";
            echo $date. "\r\n";
            echo $today. "\r\n";
        }   
    
    }
    ?>
    

    这里的沙盒:http://sandbox.onlinephpfunctions.com/code/fae07419c11f38454de9f3d301cfd1b87816ff82

    【讨论】:

      【解决方案4】:

      据我了解,您正在尝试将当前月份中 $today 之前的所有日期显示为过去日期,并将当前月份中 $today 之后的所有日期显示为 FUTURE 日期,并将 $today 日期显示为 TODAY。

      您的代码看起来是正确的,但 '' 比较适用于数字而不是字符串。您需要使用 strtotime 函数将日期转换为时间戳。

      【讨论】:

        猜你喜欢
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-04
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多