谨慎使用php的strtotime()函数
我们在日常业务中,针对业务量,经常会采用对数据库按时间做横向分表,分表后的查询往往会涉及到时间问题。例如,我们想查询某个用户距离当前时间1个月的订单情况,在这个时候,我们有些会用到strtotime()函数去处理。
但是使用strtotime(),需要非常谨慎。我们先看一段代码,代码目的是想拿到几个月以前的年份月份,例如今天是2014年8月1号,我想拿到2个月前的年份月份是 array("0"=>"201406", "1"=>"201407",)
- /****
- *$mthNum 几月以前
- * return like array('0'=>'201401','1'=>'201402'),结果不包含当前月份
- ************/
- function getTimeYm($mthNum)
- {
- $timeArr = array();
- if($mthNum <= 0)
- return $timeArr;
- do
- {
- $timeArr[] = date("Ym", strtotime("-$mthNum month"));
- $mthNum --;
- }
- while ($mthNum > 0);
- return $timeArr;
- }
表面看代码似乎没有问题,但是我们做个测试,下面是测试代码,测试的目的很简单,只是想测试一下,每个月最后一天的前一个月的日期是多少
- <?php
- $dateArr = array(
- "2014-01-31 00:00:00 -1 month",
- "2014-02-28 00:00:00 -1 month",
- "2014-03-31 00:00:00 -1 month",
- "2014-04-30 00:00:00 -1 month",
- "2014-05-31 00:00:00 -1 month",
- "2014-06-30 00:00:00 -1 month",
- "2014-07-31 00:00:00 -1 month",
- "2014-08-31 00:00:00 -1 month",
- "2014-09-30 00:00:00 -1 month",
- "2014-10-31 00:00:00 -1 month",
- "2014-11-30 00:00:00 -1 month",
- "2014-12-31 00:00:00 -1 month",
- );
- foreach ($dateArr as $val)
- {
- $time = strtotime($val);
- echo [$time][$val]."\r\n";
- }
我们看一下测试结果,从测试结果中,我们发现我们忽略了每个月天数不同,那么strtotime()会带来不一样的结果
那么究竟 strtotime("-$n month") 是怎么计算的呢?在做一个测试,如下:查看一下结果
- <?php
- $testTime = date("Y-m-d H:i:s", time());
- echo "测试时间:{$testTime} \r\n";
- $flag = 0;
- $time = 0;
- $tmp = 0;
- while(1)
- {
- if($flag ++ > 12)
- break;
- $time = strtotime("-$flag month");
- $monthDiff = ($time - $tmp)/86400; //86400 = 24 * 60 * 60,
- $tmp = $time;
- $dispDate = date("Y-m-d H:i:s", $time);
- echo "{$flag}月前: {$time}, 日期:{$dispDate)} 差值:{$dispDate}天 \r\n";
- }
通过这个我们发现原来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")处理我们的需求呢?
下面提供一段手写代码供参考
- /****************
- *解决两个时间段之间的年月
- * $btm, $etm 是unix时间戳
- *****************/
- function getTimeDis($btm, $etm)
- {
- $resArr = array();
- if($etm < $btm)
- return $resArr;
- //将btm和etm都转成每月1号
- $btmc = strtotime(date("Y-m-01 00:00:00", $btm));
- $etmc = strtotime(date("Y-m-01 00:00:00", $etm));
- $flag = 0; //时间差标识符
- $resArr[] = date("Ym", $etmc);
- while(1)
- {
- $flag ++;
- $compTime = strtotime("-{$flag} month", $etmc);
- if($compTime < $btm)
- break;
- $resArr[] = date("Ym", $compTime);
- }
- return array_unique($resArr);
- }
谨慎使用php的strtotime()函数的更多相关文章
- C#时间转整型(时间戳),模仿php strtotime函数的部分功能
今天需要将一个基于MS SQL数据库的新闻系统数据导入phpcms v9,源系统新闻日期格式为"2014-01-15 10:45:49",而phpcms中使用的是整型时间戳,在ph ...
- PHP中strtotime函数使用方法分享
在PHP中有个叫做strtotime的函数.strtotime 实现功能:获取某个日期的时间戳,或获取某个时间的时间戳.strtotime 将任何英文文本的日期时间描述解析为Unix时间戳[将系统时间 ...
- (转载)PHP strtotime函数详解
(转载)http://www.jb51.net/article/21495.htm strtotime函数是一个很好的函数,灵活的运用它,会给你的工作带来不少方便.但PHP的手册中却对此函数的参数没作 ...
- php中的date和strtotime函数妙用
php中的两个常用的日期相关函数date和strtotime,相信大家一定不陌生.但我们平时使用都只是基本功能,什么时间戳变日期格式,日期格式变时间戳. 其实这两个函数还有更深的用法: 1.date函 ...
- PHP用strtotime()函数比较两个时间的大小实例详解
在PHP开发中,我们经常会对两个时间的大小进行判断,但是,在PHP中,两个时间是不可以直接进行比较,因为时间是由年.月.日.时.分.秒组成的,所以,如果需要将两个时间进行比较的话,我们首先要做的就是将 ...
- mysql常用内置函数-查询语句中不能使用strtotime()函数!
来自:http://yushine.iteye.com/blog/775407 FROM_UNIXTIME把 unix时间戳转换为标准时间 unix_timestamp把标准时间转换为 unix时间戳 ...
- PHP strtotime() 函数
------------恢复内容开始------------ 实例 将任何字符串的日期时间描述解析为 Unix 时间戳: <?php // 设置时区 date_default_timezone_ ...
- PHP的性能大坑--strtotime函数
最近在做一个游戏数据统计后台,最基础的功能是通过分析注册登录日志来展示用户数据.在公司内部测试,用户量很少,所以就没有发现什么性能问题.但是这两天一起放到真实的测试环境,用户量噌噌地就涌进来了,从下午 ...
- [PHP] 重回基础(date函数和strtotime函数)
date():格式化一个本地时间或者日期,当前时间 2016年5月13日 15:19:49 使用函数date(),输出当前是月份中的第几天,参数:String类型 d 例如:echo date(&qu ...
随机推荐
- linux性能优化
一.最小化安装系统二.关闭NetworkManager服务. NetworkManger服务如果启动,当你手动配置网卡时会发生冲突 [root@linuxangel ~]# /etc/init.d/N ...
- msql修改字符
我申请了一个jsp空间,把数据库传上去,编码如下mysql> show variables like '%char%';+--------------------------+--------- ...
- hdoj 3746 Cyclic Nacklace【KMP求在结尾加上多少个字符可以使字符串至少有两次循环】
Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- [置顶] Linux高编之进程--------fork函数的同步与异步(兄弟子进程和父子孙进程示列)
前面讲述的fork函数的基本用法,下面通过两个程序来说明fork函数同步与异步之间的关系: <1>通过fork函数实现在父进程下的四个兄弟子进程(即异步) : 函数实现代码: #inclu ...
- HTML5 Security Cheatsheet使用说明
1.URL: https://html5sec.org/ 2.通过点击如图button(也可点击其他:xss firefox)那行的button可以搜索所有button的Cheatsheet,查看都有 ...
- w10 系统升级
怎么把电脑升级到w10系统? 下载一个软件,Windows10Upgrade9252.exe, 5M左右,把windows更新开启后,运行即可! 升级后,请把windows.old 文件夹删除,这个文 ...
- 快速幂模m算法
给你三个数,a,b,m 求a^b%m的值. 如果b过大,用普通的快速幂会超时. 所以将b=2^0*b0+2^1*b+b1...... 然后,你们利用初中的知识就知道怎么做了. 继续,上代码. #inc ...
- hadoop实例
一篇讲得很好的hadoop实例,非常适合初学者学习hadoop. 本文转载自:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.ht ...
- Vim 程序编辑器 经常使用操作
按下 i 进入编辑模式 wq! 强制保存并退出 q! 不保存,强制退出 !有强制的意思 方向键位: k h j l Ctrl + f 向下移动一页 Ctrl + b 向上移动一页 0 一行的开头 ...
- linux块设备IO栈浅析
http://www.sysnote.org/2015/08/06/linux-io-stack/