谨慎使用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 ...
随机推荐
- MIPI总结和MIPI规格说明书
1. MIPI 因为是差分信号,所以时钟和数据lane 都是一对一对的,对应的即是: 1land = lane(N) + lane(P). 分享mipi 规格说明书文档如下: http://yun.b ...
- ACM1997_汉诺栽塔VII
#include <stdio.h> #include <iostream> #include <queue> #include <stdlib.h> ...
- ContentProvider初阶Cookbook
在Android世界里,ContentProvider将数据存储抽象成了类似SQL的形式,通过insert, delete, update, query等接口实现对数据的增删改查.通过ContentP ...
- XMPP and Asterisk integration
http://www.mundoopensource.com.br/en_page_xmpp_asterisk_pratical_example/ www.mundoopensource.com.br ...
- Java的序列化与反序列化(一):初识
Java提供了一种对象序列化的机制:一个对象可以被表示为一个字节序列,该字节序列包含对象的数据.有关对象的类型的信息和存储在对象中数据的类型. 将序列化对象写入文件之后,可以从文件中读取出来,并且对它 ...
- 访问者模式(Visitor)
@@@模式定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下 定义作用于这些元素的新操作. @@@练习示例: 扩展客户管理的功能 @@@示例代码: \patter ...
- IOS开发中ARC下的assign和weak区别
在ARC中的assign和weak可以说非常相像,导致有很多人误以为他们是一摸一样的,在任何时候都可以划等价,但事实却不是这样. 在群里,有人问,id类型的delegate属性到底是用assign还是 ...
- NIO设置SO_LINGER引发的异常
欢迎关注Github:https://github.com/teaey/ ### 背景 银时跟我讲,想从 Netty3迁移到Netty4 . 问其原因是由于 Netty3在容器里会报错,错误堆栈: j ...
- Objective-C--Runtime机制
个人理解: 简单来说,Objective-C runtime是一个实现Objective-C语言的C库.对象可以用C语言中的结构体表示,而方法(methods)可以用C函数实现.事实上,他们 差不多也 ...
- iOS UIKit:viewController之Segues (4)
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...