0

我想将时间转换为四舍五入的时间。
因此我只想以秒为单位使用间隔。它适用于一刻钟和整小时。但不是几天。然后就乱了。但我不明白为什么

这是我的功能:

function formatToMySQLTime($sTime,$iInterval){
    switch ($iInterval){
        case 1: // 15 minutes;
            $iDivider = 15 * 60;
            break;
        case 2: // 1 hour
            $iDivider = 60 * 60;
            break;
        case 3: // 1 day
            $iDivider = 60 * 60 * 24;
            break;
    }    
    $iRemainder = strtotime($sTime) % $iDivider;
    $iRoundTime = strtotime($sTime) - $iRemainder;    
    $sTime = date('Y-m-d H:i:s', $iRoundTime);
    return $sTime;
}

这是输出:

echo formatToMySQLTime('2013-10-21 03:23:00',1);
2013-10-21 03:15:00

echo formatToMySQLTime('2013-10-21 03:23:00',2);
2013-10-21 03:00:00

echo formatToMySQLTime('2013-10-21 03:23:00',3);
2013-10-21 02:00:00

第三个输出错误,应该是2013-10-21 00:00:00. 我的错误是什么?

4

2 回答 2

1

您有时区问题,因为strtotime函数不知道时区,并且date是。 UTC您可以通过将字符串附加到变量来在本地设置它,而不是设置全局时区,$sTime而不是使用date()use gmdate()

// it doesn't matter in which timezone your are, function works with UTC
date_default_timezone_set('Europe/Berlin');

function formatToMySQLTime($sTime, $iInterval) {
    switch ($iInterval){
        case 1: // 15 minutes;
            $iDivider = 15 * 60;
            break;
        case 2: // 1 hour
            $iDivider = 60 * 60;
            break;
        case 3: // 1 day
            $iDivider = 60 * 60 * 24;
            break;
    }
    $U = strtotime($sTime . ' UTC');
    $iRoundTime = $U - $U % $iDivider;    
    return gmdate('Y-m-d H:i:s', $iRoundTime);
}
    
echo formatToMySQLTime('2013-10-21 03:23:00',1);
echo formatToMySQLTime('2013-10-21 03:23:00',2);
echo formatToMySQLTime('2013-10-21 03:23:00',3);

运行代码


更新:

您可以在DateTime 类的帮助下使函数更加通用和可读,而不是修改每个时间间隔的函数,例如:

function formatToMySQLTime($sTime, $iInterval) {
    $dt = new DateTime($sTime, new DateTimezone('UTC'));
    $U = $dt->getTimestamp();

    $dt2 = clone $dt;
    $interval = DateInterval::createFromDateString($iInterval);
    $iDivider = $dt2->add($interval)->getTimestamp() - $U;
    
    $dt->setTimestamp($U - $U % $iDivider);
    return $dt->format('Y-m-d H:i:s');
}

echo formatToMySQLTime('2013-10-21 03:23:00', '15 minute');
echo formatToMySQLTime('2013-10-21 03:23:00', '1 hour');
echo formatToMySQLTime('2013-10-21 03:23:00', '1 day');

运行代码

于 2013-10-29T09:25:58.860 回答
0

我的错误是什么?

整个方法是有缺陷的。

如果您检查您的$iRemainder,您会看到它包含一个日期值,例如Thu, 01 Jan 1970 23:01:48 +0100- 从您的原始值中减去它并再次添加“一天的秒数”当然会因为 DST 引起的不同时间而变得混乱。

在使用 unix 时间戳时,假设一天总是包含一定数量的秒是完全错误的——因为DST 之类的事情。

顺便说一句,根据您的示例,您实际上并没有“四舍五入”-对于前两个,您要四舍五入接下来的 15 分钟或整小时,但是对于第三个,您要四舍五入当天-什么是这背后的逻辑?

我建议您单独查看日期的必要部分,然后返回格式化的日期,其余部分只需手动设置为匹配值。

于 2013-10-29T09:19:09.417 回答