格式化DateTime Diff以防止在PHP中显示0年0个月

时间:2015-12-03 05:44:20

标签: php mysql date datetime

我试图从数据库中找出今天的日期和特定日期之间的差异 我使用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是2015年12月3日,我得到的输出是 0年0个月和6天,而我希望它只显示 6天

3 个答案:

答案 0 :(得分:2)

请检查以下格式:

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个月)

答案 1 :(得分:0)

爆炸时间不同的值并检查日期格式是否为0,如下所示

user.to_json(methods: [:encrypted_password])

答案 2 :(得分:0)

好吧,我想提出一个比以下内容更简单的方法(这首先使我来到这里),但是我认为这是对公认答案的改进。从技术上讲,它也稍短一些,但更重要的是,它可以适应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的要求,除了最后一个“和” 单词(作为选项传递)之外。