• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

谨慎使用php的strtotime()函数

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  我们在日常业务中,针对业务量,经常会采用对数据库按时间做横向分表,分表后的查询往往会涉及到时间问题。例如,我们想查询某个用户距离当前时间1个月的订单情况,在这个时候,我们有些会用到strtotime()函数去处理。

  但是使用strtotime(),需要非常谨慎。我们先看一段代码,代码目的是想拿到几个月以前的年份月份,例如今天是2014年8月1号,我想拿到2个月前的年份月份是 array("0"=>"201406", "1"=>"201407",)

 1 /****
 2 *$mthNum 几月以前
 3 * return like array('0'=>'201401','1'=>'201402'),结果不包含当前月份
 4 ************/
 5 function getTimeYm($mthNum)
 6 {
 7     $timeArr = array();
 8     
 9     if($mthNum <= 0)
10         return $timeArr;
11 
12     do 
13     {
14         $timeArr[] = date("Ym", strtotime("-$mthNum month"));
15         $mthNum --;
16     }
17     while ($mthNum > 0);
18 
19     return $timeArr;
20 }

  

  表面看代码似乎没有问题,但是我们做个测试,下面是测试代码,测试的目的很简单,只是想测试一下,每个月最后一天的前一个月的日期是多少

 1 <?php
 2 $dateArr = array(
 3     "2014-01-31    00:00:00 -1 month",
 4     "2014-02-28    00:00:00 -1 month",
 5     "2014-03-31    00:00:00 -1 month",
 6     "2014-04-30    00:00:00 -1 month",
 7     "2014-05-31    00:00:00 -1 month",
 8     "2014-06-30    00:00:00 -1 month",
 9     "2014-07-31    00:00:00 -1 month",
10     "2014-08-31    00:00:00 -1 month",
11     "2014-09-30    00:00:00 -1 month",
12     "2014-10-31    00:00:00 -1 month",
13     "2014-11-30    00:00:00 -1 month",
14     "2014-12-31    00:00:00 -1 month",
15 );
16 
17 foreach ($dateArr as $val)
18 {
19     $time = strtotime($val);
20     echo [$time][$val]."\r\n";
21 }  

  我们看一下测试结果,从测试结果中,我们发现我们忽略了每个月天数不同,那么strtotime()会带来不一样的结果

 

  那么究竟 strtotime("-$n month") 是怎么计算的呢?在做一个测试,如下:查看一下结果

 1 <?php
 2 
 3 $testTime = date("Y-m-d H:i:s", time());
 4 echo "测试时间:{$testTime}  \r\n";
 5 
 6 $flag = 0; 
 7 $time = 0;
 8 $tmp  = 0;
 9 
10 while(1)
11 {
12     if($flag ++ > 12)
13         break;
14 
15     $time      =  strtotime("-$flag month");
16     $monthDiff = ($time - $tmp)/86400;  //86400 = 24 * 60 * 60,
17     $tmp       = $time;
18 
19     $dispDate = date("Y-m-d H:i:s", $time);
20 
21     echo "{$flag}月前: {$time},  日期:{$dispDate)}   差值:{$dispDate}天 \r\n";
22 }

 

 

通过这个我们发现原来strtotime("-$n month")是这样计算的 (注:strtotime("-$n month"),第二个参数省略,第二个参数表示距离的时间,省略表示当前时间)

  时间

差值

理论时间

结果

7月31号

1月前

6月31号

6月只有30天,则加一天到7月1号

7月31号

2月前

5月31号

 

7月31号

3月前

4月31号

4月只有30天,则加一天到5月1号

……

 

那么如果这样的话,我们怎么用strtotime("-$n month")处理我们的需求呢?

下面提供一段手写代码供参考

 1 /****************
 2 *解决两个时间段之间的年月
 3 * $btm, $etm 是unix时间戳
 4 *****************/
 5 function getTimeDis($btm, $etm)
 6 {
 7     $resArr = array();
 8     if($etm < $btm)
 9         return $resArr;
10 
11     //将btm和etm都转成每月1号
12     $btmc = strtotime(date("Y-m-01 00:00:00", $btm));
13     $etmc = strtotime(date("Y-m-01 00:00:00", $etm));
14 
15 
16     $flag = 0; //时间差标识符
17     $resArr[] = date("Ym", $etmc);
18 
19     while(1)
20     {
21         $flag ++;
22         $compTime = strtotime("-{$flag} month",  $etmc);
23         
24         if($compTime < $btm)
25             break;
26 
27         $resArr[] = date("Ym", $compTime);
28     }
29 
30     return array_unique($resArr);
31 }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
深入理解PHP内核(四)概览-PHP脚本的执行发布时间:2022-07-10
下一篇:
PHPGUID和UUID生成类发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap