【问题标题】:Format DateTime Diff to prevent showing 0 years 0 months in PHP格式化 DateTime Diff 以防止在 PHP 中显示 0 年 0 个月
【发布时间】:2015-12-03 05:44:19
【问题描述】:

我正在尝试从数据库中找出今天日期与特定日期之间的差异。
我使用 DateTime Diff 来获得结果,它以 (年月和日) 格式为我提供了正确答案。唯一的问题是,如果差异小于一年,它会显示 0 年,这是不希望的。几个月和几天都一样。
是否可以检查这 3 个值中的任何一个是否为 0,或者是否有其他方法可以完成此操作?

这是我正在使用的代码-

$datetime1 = new DateTime($asset[$a]['PDate']);
$datetime2 = new DateTime("now");
$interval = $datetime1->diff($datetime2);
echo $interval->format('%y years %m months and %d days');

$datetime1 来自数据库,而 $datetime2 显示今天的日期。如果 $datetime1 类似于 12/9/2015 & %datetime2 是 12/3/2015 我得到的输出是 0 年 0 个月零 6 天 而我希望它只显示 6天

【问题讨论】:

    标签: php mysql date datetime


    【解决方案1】:

    所以请检查如下格式:

    if($datetime1->format('%y') != 0)
        echo $datetime1->format('%y years %m months and ');
    if($datetime1->format('%y') == 0 && $datetime1->format('%m') != 0)
        echo $datetime1->format('%m months and ');
    echo $datetime1->format('%d days');
    

    或(重组):

    if($datetime1->format('%y') != 0) {
        echo $datetime1->format('%y years %m months and ');
    } else {
        if($datetime1->format('%m') != 0)
            echo $datetime1->format('%m months and ');
    }
    echo $datetime1->format('%d days');
    

    这将输出:

    2年2个月零2天
    2 个月零 2 天(如果是 0 年)
    2 天(如果是 0 年零 0 个月)
    2 年 0 个月零 2 天(如果是 0 个月)

    如果月份的值为 0,则不应打印月份(与年份无关)

    $flag = false;
    if($datetime1->format('%y') != 0) {
        echo $datetime1->format('%y years ');
        $flag= true;
    }
    if($datetime1->format('%m') != 0) {
        echo $datetime1->format('%m months ');
        $flag= true;
    }
    if($datetime1->format('%d') != 0) {
        echo $flag?"and ":"";
        echo $datetime1->format('%d days');
    }
    

    这将输出:

    2年2个月零2天
    2 个月零 2 天(如果是 0 年)
    2 天(如果 0 年零 0 个月)
    2年2天(如果是0个月)

    【讨论】:

    • 是的!无论如何,我不得不重组以摆脱 0 个月
    • 我认为如果有年份你需要打印月份。立即查看更新的答案。现在月份的值为 0 时不会打印。
    • 不,我只是想打印非零值。非常感谢您的帮助!
    • 记得使用$intervall->format() 而不是$datetime1->format()
    【解决方案2】:

    分解时间差异的值并检查日期格式是否为0,如下所示

    $datetime1 = new DateTime($asset[$a]['PDate']);
    $datetime2 = new DateTime("now");
    $interval = $datetime1->diff($datetime2);
    $different= $interval->format('%y years %m months and %d days');
    
    //eg :$different= '1 years 1 months and 7 days';
    $a=explode(' ',$different);
    print_r($a);
    if($a[0]>0){
    $y=$a[0]."years  ";
    }else{$y="";}
    if($a[2]>0){
    $m=$a[2]."months  ";
    }else{$m="";}
    if($a[5]>0){
    $d=$a[5]."days   ";
    }
    echo $y,$m,$d;
    

    【讨论】:

    • @Shashank Surwase:这个答案不符合您的期望吗?
    【解决方案3】:

    好吧,我想提出比以下更简单的方法(这也是我最初来到这里的原因),但我认为这是对公认答案的改进。它在技术上也有点短,但更重要的是它适应了 0 天的边缘情况。 (在接受的答案中将打印y years m months 省略单词“and”):

    <?php 
    
    $datetime1 = new DateTime($asset[$a]['PDate']);
    $datetime2 = new DateTime;
    $interval = array_filter((array) $datetime1->diff($datetime2));
    
    $spec = ['y' => 'years', 'm' => 'months', 'd' => 'days'];
    foreach ($spec as $key => $unit) {
        if (array_key_exists($key, $interval)) {
            $out[] = "{$interval[$key]} $unit";
        }
    }
    
    if ((count($out)) > 1) {
        $last = array_pop($out);
        $out[] = "and $last";
    }
    
    echo implode(' ', $out);
    

    这是因为DateInterval 对象(由对DateTime::diff() 的调用产生)包含公共属性,这些属性在转换为数组时映射到关联键。 array_filter 默认删除等于零的值。

    还有其他改进/考虑;例如,要遵循复数规则,您可以在forloop 中添加条件:

    $spec = ['y' => 'year', 'm' => 'month', 'd' => 'day'];
    foreach ($spec as $key => $unit) {
        if (array_key_exists($key, $interval)) {
            $value = $interval[$key];
            if ($value > 1) {
                $unit .= 's';
            }
            $out[] = "$value $unit";
        }
    }
    

    或者也许您想用逗号加入,除了最后一个元素,在这种情况下,最后一段代码将被重写:

    $last = array_pop($out);
    if ((count($out)) > 0) {
        $last = implode(', ', $out) . " and $last";
    }
    
    echo $last;
    

    你可以在这里看到它作为一个函数的作用:https://3v4l.org/vYsE7 或者,如果您更喜欢简明的问题特定变体:https://3v4l.org/9FBP5

    该函数非常模块化,但默认几乎完全符合 OP 的要求,除了作为选项传入的最后一个 " 和 " 单词。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多