PHP DateTime四舍五入到最近的10分钟

Dan*_*Dan 11 php datetime

我检索从MySQL领域的日期时间,但我需要详谈到最近的10分钟.

例如,如果日期时间是2013-11-06 14:00:01,我想将时间返回到2013年6月11日14:10.

最简单的方法是什么?

$datetime = new DateTime($mysqldata);

echo $datetime->format('d/m/Y G:i');
Run Code Online (Sandbox Code Playgroud)

任何建议表示赞赏

谢谢.

ran*_*and 15

1)如有必要,将秒数设置为0(通过四舍五入到最接近的分钟)

$second = $datetime->format("s");
if($second > 0)
    $datetime->add(new DateInterval("PT".(60-$second)."S"));
Run Code Online (Sandbox Code Playgroud)

2)得到分钟

$minute = $datetime->format("i");
Run Code Online (Sandbox Code Playgroud)

3)转换模10

$minute = $minute % 10;
Run Code Online (Sandbox Code Playgroud)

4)如有必要,将分钟计数到下一个10分钟

if($minute != 0)
{
    // Count difference
    $diff = 10 - $minute;
    // Add difference
    $datetime->add(new DateInterval("PT".$diff."M"));
}
Run Code Online (Sandbox Code Playgroud)

编辑,感谢@Ondrej Henek和@berturion


小智 14

当我们要舍入的DateTime已经是10分钟的倍数时,@rand的答案有一个错误.它将在10分钟后跳到不想要的时候.

此外,($datetime->add(new \DateInterval("PT".(60-$second)."S"));当秒已经为零时,总是跳到下一分钟.

此增强功能修复了这些错误,并采用$ precision参数来涵盖更多用例.

function roundTime(\DateTime &$datetime, $precision = 30, $round_lower = false) {
    // 1) Set number of seconds to 0 (by rounding up to the nearest minute if necessary)
    $second = (int) $datetime->format("s");
    if ($second > 30 && $round_lower == false) {
        // Jumps to the next minute
        $datetime->add(new \DateInterval("PT".(60-$second)."S"));
    } elseif ($second > 0) {
        // Back to 0 seconds on current minute
        $datetime->sub(new \DateInterval("PT".$second."S"));
    }
    // 2) Get minute
    $minute = (int) $datetime->format("i");
    // 3) Convert modulo $precision
    $minute = $minute % $precision;
    if ($minute > 0) {
        if($round_lower) {
            $datetime->sub(new \DateInterval("PT".$minute."M"));
        } else {
            // 4) Count minutes to next $precision-multiple minutes
            $diff = $precision - $minute;
            // 5) Add the difference to the original date time
            $datetime->add(new \DateInterval("PT".$diff."M"));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这个功能现在非常适合我的使用,也可能适合其他人.

  • @StephenR`$ datetime`是一个对象,因此默认情况下通过引用传递 (2认同)

esq*_*lin 7

我偶然发现了这个问题,想知道为什么所有的解决方案都那么复杂。就是这样:

function roundToNext10Min(\DateTime $dt, $precision = 10) {
    $s = $precision * 60;
    $dt->setTimestamp($s * ceil($dt->getTimestamp() / $s));
    return $dt;
}

$dt = roundToNext10Min(new DateTime($str));
echo $dt->format('d/m/Y G:i');
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用ceil,floor和round函数将DateTime向上,向下或最近的分钟间隔舍入,如下所示:

/**
 * @param \DateTime $dateTime
 * @param int $minuteInterval
 * @return \DateTime
 */
public function roundUpToMinuteInterval(\DateTime $dateTime, $minuteInterval = 10)
{
    return $dateTime->setTime(
        $dateTime->format('H'),
        ceil($dateTime->format('i') / $minuteInterval) * $minuteInterval,
        0
    );
}

/**
 * @param \DateTime $dateTime
 * @param int $minuteInterval
 * @return \DateTime
 */
public function roundDownToMinuteInterval(\DateTime $dateTime, $minuteInterval = 10)
{
    return $dateTime->setTime(
        $dateTime->format('H'),
        floor($dateTime->format('i') / $minuteInterval) * $minuteInterval,
        0
    );
}

/**
 * @param \DateTime $dateTime
 * @param int $minuteInterval
 * @return \DateTime
 */
public function roundToNearestMinuteInterval(\DateTime $dateTime, $minuteInterval = 10)
{
    return $dateTime->setTime(
        $dateTime->format('H'),
        round($dateTime->format('i') / $minuteInterval) * $minuteInterval,
        0
    );
}
Run Code Online (Sandbox Code Playgroud)