【问题标题】:Rounding a MYSQL datetime to earliest 15 minute interval in milliseconds (PHP)将 MYSQL 日期时间四舍五入到最早的 15 分钟间隔(以毫秒为单位)(PHP)
【发布时间】:2011-03-28 22:40:39
【问题描述】:

我正在从 MYSQL 获取日期时间,如下所示:

2010-08-11 11:18:28

我需要将其转换为“地板”或最早的 15 分钟间隔,并以毫秒为单位输出另一个函数。

所以,这种情况是:

2010-08-11 11:15:00 以毫秒为单位


哎呀!抱歉 - 需要澄清 - 我需要将其转换为 php 内毫秒的代码!


进行计时测试发现以下内容:

$time_start = microtime(true);
for($i=0;$i<10000;$i++)
    floor(strtotime('2010-08-11 23:59:59')/(60*15))*60*15*1000;
$time_end = microtime(true);
echo 'time taken = '.($time_end - $time_start);

所用时间 = 21.440743207932

$time_start = microtime(true);
for($i=0;$i<10000;$i++)
    strtotime('2010-08-11 23:59:59')-(strtotime('2010-08-11 23:59:59') % 900);
$time_end = microtime(true);
echo 'time taken = '.($time_end - $time_start);

所用时间 = 39.597450017929

$time_start = microtime(true);
for($i=0;$i<10000;$i++)
    bcmul((strtotime('2010-08-11 23:59:59')-(strtotime('2010-08-11 23:59:59') % 900)), 1000);
$time_end = microtime(true);
echo 'time taken = '.($time_end - $time_start);

所用时间 = 42.297260046005

$time_start = microtime(true);
for($i=0;$i<10000;$i++)
    floor(strtotime('2010-08-11 23:59:59')/(900))*900000;
$time_end = microtime(true);
echo 'time taken = '.($time_end - $time_start);

所用时间 = 20.687357902527

所用时间 = 19.32729101181

所用时间 = 19.938629150391

似乎 strtotime() 函数很慢,我们可能应该避免在每次需要时重复使用它。 timetaken(60*15) != timetaken(900) 有点意外……

【问题讨论】:

    标签: php mysql datetime time floor


    【解决方案1】:

    这行得通吗?难道没有一些功能可以做得更好吗?

    echo floor(strtotime('2010-08-11 11:18:28')/(60*15))*60*15*1000;
    1281505500000
    Wednesday, August 11, 2010 11:15:00 AM
    
    echo floor(strtotime('2010-08-11 11:28:28')/(60*15))*60*15*1000;
    1281505500000
    Wednesday, August 11, 2010 11:15:00 AM
    
    echo floor(strtotime('2010-08-11 00:00:00')/(60*15))*60*15*1000;
    1281465000000
    Wednesday, August 11, 2010 12:00:00 AM
    
    echo floor(strtotime('2010-08-11 23:59:59')/(60*15))*60*15*1000;
    1281550500000
    Wednesday, August 11, 2010 11:45:00 PM
    

    【讨论】:

      【解决方案2】:

      以下将为您提供最早的 15 分钟间隔:

      select UNIX_TIMESTAMP(YOURDATETIME)-MOD(UNIX_TIMESTAMP(YOURDATETIME), 900) 
      from YOURTABLE
      

      结果以纪元秒为单位(自 '1970-01-01 00:00:00' UTC 以来的秒数),如果您想要以毫秒为单位的值,您应该乘以 1000(在查询中或在 PHP 中,因为您看合适)。

      编辑

      在 PHP 中,您的一组值将是:

      $values = array('2010-08-11 11:18:28', '2010-08-11 11:28:28', '2010-08-11 00:00:00', '2010-08-11 23:59:59');
      foreach($values as $value) {
          $result = (strtotime($value)-(strtotime($value) % 900));
          echo "$value -> $result\n";
      }
      

      当您将 $result 乘以 1000(以获取以 ms 为单位的值)时,您可能会出现溢出,结果将被转换为浮点数。这可能不是你想要的,所以你最好使用bcmul

      $result = bcmul((strtotime($value)-(strtotime($value) % 900)), 1000);
      

      【讨论】:

      • 嗨!这对于 mysql 来说看起来很不错,有没有像这样的聪明方法在 php 中做同样的事情?
      【解决方案3】:

      试一试,看看会发生什么:

      select DATE(myColumn) 
             + CONVERT(HOUR(myColumn),CHAR(2)) + ':'
             + CASE 
               WHEN MINUTE(myColumn) < 15 THEN '00'
               WHEN MINUTE(myColumn) < 30 THEN '15'
               WHEN MINUTE(myColumn) < 45 THEN '30'
               ELSE '45'
             END 
             + ':00' as myDate
      

      【讨论】:

        【解决方案4】:

        好吧,让我们看看最坏的解决方案:

        <?php
        
        $ts    = explode(' ', '2010-08-11 11:18:28');
        $date  = explode('-', $ts[0]);
        $time  = explode(':', $ts[1]);
        $ts    = mktime($time[0], $time[1], $time[2], $date[1], $date[2], $date[0]);
        $floor = mktime($time[0], round($time[1]/15)*15, 0, $date[1], $date[2], $date[0]);
        

        【讨论】:

          猜你喜欢
          • 2013-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-24
          • 2020-03-23
          • 2014-12-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多