我想将时间转换为舍入时间。
因此,我只想使用以秒为单位的间隔。它适用于四分之一小时和整小时。但不是几天。然后就搞砸了。但我不明白为什么
这是我的函数:
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
.我的错误是什么?
您有时区问题,因为strtotime
函数无法识别时区,而date
是。您可以通过将 UTC
字符串附加到$sTime
变量来在本地设置全局时区,而不是使用date()
使用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');
运行代码。
我的错误是什么?
整个方法都是有缺陷的。
如果您检查$iRemainder
,您会看到它包含一个日期值,例如 Thu, 01 Jan 1970 23:01:48 +0100
- 并且从原始值中减去它并再次添加"一天的秒数"当然会因 DST 引起的不同时间而变得混乱。
在使用 unix 时间戳时,假设一天总是包含一定数量的秒是完全错误的——因为 DST 之类的东西。
顺便说一句,根据你的例子,你实际上并没有"四舍五入"——对于前两个,你四舍五入到接下来的 15 分钟或整小时,但对于第三个你想四舍五入到一天——这背后的逻辑是什么?
我建议您单独查看日期的必要部分,然后返回格式化日期,其余部分仅手动设置为匹配值。