你真的了解strtotime('X month')吗
经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌…
今天是2018-08-31 执行代码:
date("Y-m-d",strtotime("+1 month"))
怎么输出是2018-10-01?
虽然这个问题看起来很迷惑, 但从内部逻辑上来说呢, 其实是”对”的
date内部的对于这种事情的处理逻辑:
- 先做-1 month, 那么当前是07-31, 减去一以后就是06-31.
- 再做日期规范化, 因为6月没有31号, 所以就好像2点60等于3点一样, 6月31就等于了7月1
是不是逻辑很”清晰”呢? 我们也可以手动验证第二个步骤, 比如:
var_dump(date("Y-m-d", strtotime("2017-06-31")));
//输出2017-07-01
也就是说, 只要涉及到大小月的最后一天, 都可能会有这个迷惑, 我们也可以很轻松的验证类似的其他月份, 印证这个结论:
var_dump(date("Y-m-d", strtotime("-1 month", strtotime("2017-03-31"))));
//输出2017-03-03
var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2017-08-31"))));
//输出2017-10-01
var_dump(date("Y-m-d", strtotime("next month", strtotime("2017-01-31"))));
//输出2017-03-03
var_dump(date("Y-m-d", strtotime("last month", strtotime("2017-03-31"))));
//输出2017-03-03
那怎么办呢?
从PHP5.3开始呢, date新增了一系列修正短语, 来明确这个问题, 那就是”first day of” 和 “last day of”, 也就是你可以限定好不要让date自动”规范化”:
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime("2017-03-31"))));
//输出2017-02-28
var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime("2017-08-31"))));
////输出2017-09-01
var_dump(date("Y-m-d", strtotime("first day of next month", strtotime("2017-01-31"))));
////输出2017-02-01
var_dump(date("Y-m-d", strtotime("last day of last month", strtotime("2017-03-31"))));
////输出2017-02-28
那如果是5.3之前的版本(还有人用么?), 你可以使用mktime之类的, 把所有的日子忽略掉, 比如都限定为每月1号就可以了, 只不过就不如直接用first day来的更加优雅.
有人将这个问题提交为bug ,https://bugs.php.net/bug.php?id=22486
转自: http://www.laruence.com/2018/07/31/3207.html
你真的了解strtotime('X month')吗的更多相关文章
- php: +1天, +3个月, strtotime(): +1 day, +3 month
php: +1天, +3个月, strtotime(): +1 day, +3 month 比如,我现在当前时间基础上+1天: strtotime("+1 day"); 比如我现 ...
- php函数强大的 strtotime
使用strtotime可以将各种格式的时间字符串转换为时间戳 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 转换常规时间格式 echo date('Y-m-d H:i: ...
- 时间函数 date strtotime
date_default_timezone_set('Asia/Shanghai');echo strtotime('Today');echo strtotime(date('Y-m-d')); 获取 ...
- php strtotime 和 date 日期操作
time()得到的数值是1970-1-1到现在的秒数,strtotime("now")也是,两个值是相同的. http://doc.thinkphp.cn/manual/syste ...
- PHP中的strtotime()对于31日求上个月有问题
原文出处 <?php $date = "2012-07-31"; $date_unix = strtotime($date); $lastmonth = strtotime( ...
- 谨慎使用php的strtotime()函数
我们在日常业务中,针对业务量,经常会采用对数据库按时间做横向分表,分表后的查询往往会涉及到时间问题.例如,我们想查询某个用户距离当前时间1个月的订单情况,在这个时候,我们有些会用到strtotime( ...
- strtotime的几种用法区别
strtotime不仅可以使用类似Y-m-d此类标准的时间/日期字符串来转化时间戳, 还可以用类似自然语言的来生成时间戳, 类似: strtotime('last day'); strtotime(' ...
- strtotime 获取之前,之后时间
一年之前 <?php echo strtotime('-1 year'); ?> 一年之后 <?php echo strtotime('+1 year'); ?> 一月之前 & ...
- [PHP] 重回基础(date函数和strtotime函数)
date():格式化一个本地时间或者日期,当前时间 2016年5月13日 15:19:49 使用函数date(),输出当前是月份中的第几天,参数:String类型 d 例如:echo date(&qu ...
随机推荐
- 使用Vue-cli3搭建Vue+TypeScript项目
一,创建项目 使用 npm 安装 vue-cli 3 和typescript npm i -g @vue/cli typescript 使用vue create命令快速搭建新项目的脚手架 vue cr ...
- zabbix 自定义mysql监控
一.配置zabbix-agent 编辑 /etc/zabbix/zabbix_agentd.conf文件 增加如下两个配置 1.vim /etc/zabbix/zabbix_agentd.conf ...
- 离线缓存 Visual Studio 2019 (VS2019)的方法
1. 下面是以管理员身份运行命令行: https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-en ...
- 搭建rsyslog日志服务器
环境配置 centos7系统 client1:192.168.91.17 centos7系统 master:192.168.91.18 rsyslog客户端配置 1.rsyslog安装 yum ins ...
- ASP.Net Core使用Ajax局部更新
由于目前ASP.NET Core中没有提供Ajax帮助器,所以参照 上一篇帖文,使用data-ajax-*属性来使用jQuery Unobtrusive Ajax功能实现HTML的局部页面元素更新. ...
- C# 练习题 打印出100-999之间所有的”水仙花数”
题目:打印出100-999之间所有的”水仙花数”,所谓”水仙花数”是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个”水仙花数”,因为153=1的三次方+5的三次方+3的三次方.1.程序 ...
- 面试前必须要知道的21道Redis面试题
1.使用redis有哪些好处? 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 支持丰富数据类型,支持string,list,set,so ...
- web前端-js
1. js基础语法 声明变量 var a = 10; 查看变量类型 typeof a; 打印,测试语句 alert(a); #使用弹出框显示 console.log(a); #使用console ...
- dtd的引入方式
dtd三种引入方法 //第一种引入方式: //1.dtd <?xml version="1.0" encoding="UTF-8"?> <!E ...
- logstash 入门篇
场景介绍 基于分布式集群海量日志数据,且分布在不同的服务器上,日志的采集以及可视化是需要我们解决的问题.ELK就是这么一个方案,当然我们这里主要讲解logstash安装配置和基础语法. ELK帮我们解 ...