令人困惑的strtotime
经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌…
这不, 刚刚就有人在微博上又问我:
鸟哥,今天是2018-07-31 执行代码:
- date("Y-m-d",strtotime("-1 month"))
怎么输出是2018-07-01?
好的吧, 虽然这个问题看起来很迷惑, 但从内部逻辑上来说呢, 其实是”对”的, 你先别着急哈, 让我慢慢讲:
我们来模拟下date内部的对于这种事情的处理逻辑:
- 1. 先做-1 month, 那么当前是07-31, 减去一以后就是06-31.
- 2. 再做日期规范化, 因为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来的更加优雅.
现在, 搞清楚了内部原理, 是不是就不慌了?
原文出处:http://www.laruence.com/2018/07/31/3207.html
令人困惑的strtotime的更多相关文章
- PHP令人困惑的strtotime
经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌… 比如:今天 ...
- python logging模块可能会令人困惑的地方
python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...
- Java安全编码:糟糕的在线建议和令人困惑的APIs
对于程序员和软件开发人员来说,网络论坛提供了一个交流知识和寻找具体编码难题答案的好地方.遗憾的是,他们并不总是准确信息的来源. 弗吉尼亚理工大学的一组研究人员分析了数百篇关于Stack Overflo ...
- 一个令人困惑的低效SQL
整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...
- PHP最佳实践(译)
原文: PHP Best Practices-A short, practical guide for common and confusing PHP tasks 译者:youngsterxyf 最 ...
- ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus
ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus 本文承接我的上一篇博文: ASP.NET 5 Linux部署,那篇文章主要是针对最新的ASP. ...
- [转载]Google Guava官方教程(中文版)
原文链接 译文链接 译者: 沈义扬,罗立树,何一昕,武祖 校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] ...
- Python标准模块--concurrent.futures
1 模块简介 concurrent.futures模块是在Python3.2中添加的.根据Python的官方文档,concurrent.futures模块提供给开发者一个执行异步调用的高级接口.con ...
- Python标准模块--import
1 模块简介 作为一个Python初学者,你首先要学会的知识就是如何引入其它模块或者包.但是,我发现有些开发者虽然使用Python很多年,依然不了解Python引入机制的灵活性.这篇文章,我们就会研究 ...
随机推荐
- 极简 Node.js 入门 - 2.4 定时器
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 【POJ3071】Football - 状态压缩+期望 DP
Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2 ...
- CSS动画实例:Loading加载动画效果(一)
一些网站或者APP在加载新东西的时候,往往会给出一个好看有趣的Loading图,大部分的Loading样式都可以使用CSS3制作出来,它不仅比直接使用gif图简单方便,还能节省加载时间和空间.下面介绍 ...
- 每日一道 LeetCode (19):合并两个有序数组
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- 【MySQL】记一次线上重大事故:二狗子竟然把线上数据库删了!!
写在前面 估计二狗子这几天是大姨夫来了,心情很郁闷,情绪也很低落,工作的时候也有点心不在焉.让他发个版本,结果,一行命令下去把线上的数据库删了!你没听错:是删掉了线上的数据库!运营那边顿时炸了锅:怎么 ...
- ClickHouse 参数配置
转载自:https://xw.qq.com/cmsid/20200806A0PQ7X00?ADTAG=amp 在 ClickHouse 进程中,CPU 的主频越高越好,通常建议使用 32 以上的机型, ...
- layui上传同一张图片第二次时choose没有反应
将上传文件的input的val设置为空 $("#test11").parent().find("input").val('');
- 用python实现实时监控网卡流量
很多时候,我们是需要查看服务器的网卡当前跑了多大流量,但对于网卡流量的查询,在linux下似乎没有像top那样的原生命令.虽然top功能很强大,可以实时查看cpu.内存.进程的动态,但是却没有对网卡流 ...
- COS418, Distributed System, Go Language
本博客是MIT的分布式系统课程的课后作业Cos418的GO语言实现思路.由于时间有限,目前只实现了assignment1~2. 在common.go中设置debugEnabled = true,go ...
- [Redhat虚拟机安装][VirtualBox][NET:Registered protocol family 2]
错误情况 今晚试着用VirtualBox虚拟机安装RedHat,但是安装过程中一直卡在一个NET:Registered protocol family 2这个地方. 错误截图 情况如下图所示: 解决方 ...