经常会有人被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来的更加优雅.

现在, 搞清楚了内部原理, 是不是就不慌了?




												

PHP令人困惑的strtotime的更多相关文章

  1. 令人困惑的strtotime

    经常会有人被strtotime结合-1 month, +1 month, next month的时候搞得很困惑, 然后就会觉得这个函数有点不那么靠谱, 动不动就出问题. 用的时候就会很慌… 这不, 刚 ...

  2. python logging模块可能会令人困惑的地方

    python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...

  3. Java安全编码:糟糕的在线建议和令人困惑的APIs

    对于程序员和软件开发人员来说,网络论坛提供了一个交流知识和寻找具体编码难题答案的好地方.遗憾的是,他们并不总是准确信息的来源. 弗吉尼亚理工大学的一组研究人员分析了数百篇关于Stack Overflo ...

  4. 一个令人困惑的低效SQL

    整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...

  5. PHP最佳实践(译)

    原文: PHP Best Practices-A short, practical guide for common and confusing PHP tasks 译者:youngsterxyf 最 ...

  6. ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus

    ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus 本文承接我的上一篇博文: ASP.NET 5 Linux部署,那篇文章主要是针对最新的ASP. ...

  7. [转载]Google Guava官方教程(中文版)

      原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] ...

  8. Python标准模块--concurrent.futures

    1 模块简介 concurrent.futures模块是在Python3.2中添加的.根据Python的官方文档,concurrent.futures模块提供给开发者一个执行异步调用的高级接口.con ...

  9. Python标准模块--import

    1 模块简介 作为一个Python初学者,你首先要学会的知识就是如何引入其它模块或者包.但是,我发现有些开发者虽然使用Python很多年,依然不了解Python引入机制的灵活性.这篇文章,我们就会研究 ...

随机推荐

  1. Python学习系列提升篇------字符串

    字符串是python学习中重要的内容,在以后的工作中,对字符串的处理也必少不了.下面总结一下关于字符串学习的经验. 1.1 字符串的连接和合并 用‘ + ’连接,将两个字符串相加.       合并, ...

  2. 【Leetcode】【Easy】Climbing Stairs

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  3. 【Spring实战】—— 1 入门讲解

    这个系列是学习spring实战的总结,一方面总结书中所写的精髓,另一方面总结一下自己的感想. 基础部分讲解了spring最为熟知的几个功能:依赖注入/控制反转 和 面向切面编程. 这两个就不再多说了, ...

  4. HTTPS科普(转)

    为什么需要https HTTP是明文传输的,也就意味着,介于发送端.接收端中间的任意节点都可以知道你们传输的内容是什么.这些节点可能是路由器.代理等. 举个最常见的例子,用户登陆.用户输入账号,密码, ...

  5. CentOS 6.4安装谷歌浏览器(chromium)不是chrome

    原文转载于http://www.wypblog.com/archives/782 今天给大家介绍如何在CentOS 6.4平台上面安装chromium浏览器,和Google的Chrome也类似,虽然不 ...

  6. React简介

    React JS:可以用react的语法,来编写网页的交互效果 React Native:可以让我们借用react的语法来编写原生的app应用 React VR:在react的基础上去开发VR,或者说 ...

  7. solidity开发之windows下配置remix本地环境遇到的问题及解决

    本人按照这个教程配置remix本地环境.[https://cloud.tencent.com/developer/article/1374376] win+R打开管理员终端,在欲配置为本地目录的路径执 ...

  8. HDU 1754 I Hate It 【线段树单点修改 维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others ...

  9. OpenMP使用体验报告(概述)

    (本文原创,首次使用OpenMP,将使用体会记录下来供学习) OpenMP是啥玩意??? 多核多线程处理器的出现,让并行计算成为可能.在此之前,单核处理器并不能并行计算,这是很显然的,只有一个核心只能 ...

  10. HDU 2199 Can you solve this equation?(二分解方程)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2199 Can you solve this equation? Time Limit: 2000/10 ...