经常会有人被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. 慧都启动“正版IDE联合超值推广计划

    越来越多的中国软件企业为盗版所害而蒙受巨大损失,正版化意识逐渐兴起.IDE(集成开发环境)是软件开发.编写代码必备工具,而正版IDE更具有运行更稳定.编码更安全.保障更加完善等特点,逾为中国软件行业企 ...

  2. python中文入库

    http://www.cnblogs.com/evening/archive/2012/04/19/2457440.html 工作需要,将cvm.csv文件中的记录志入数据库, name, owner ...

  3. css:改变滚动条样式

    以下亲测谷歌内核的浏览器有用,微软和火狐无效 body::-webkit-scrollbar {/*滚动条整体样式*/ width: 5px; /*高宽分别对应横竖滚动条的尺寸*/ height: 1 ...

  4. python操作oracle小测试

    首先使用python操作数据库需要导入cx_Oracle包import cx_Oracle这个包需要单独下载,下载地址:https://pypi.python.org/pypi/cx_Oracle使用 ...

  5. python接口测试-项目实践(四)拼接出预期结果

    四 字符串拼接 空值处理 当某字段接口数据为空,则不显示相关字串. 比如字串原本是 "...,净资产收益率:ROE%",当接口数据中ROE为空,不显示',净资产收益率:%' 三目运 ...

  6. URL地址解析

    URL的一般格式为(带方括号[]的为可选项): protocol :// hostname[:port] / path /[?query]#fragment   1.protocol :// 为传输协 ...

  7. Android(java)学习笔记44:Map集合的遍历之键值对对象找键和值

    1. Map集合的遍历之 键值对对象找 键和值: package cn.itcast_01; import java.util.HashMap; import java.util.Map; impor ...

  8. HDU 5805

    题意: 退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nn 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后 ...

  9. [19/03/18-星期一] 常用类_Math(数学)类&Rondom(随机数)类

    一.Math(数学)类(单独一个Java.Math 包中) java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型.如果需要更加强大的数学运算能力, ...

  10. on-session问题

    .D:\0kecheng\bos\bosv2.0_chapter03.无条件查询. 方法1.@JSON(serialize=false)是注解排除不需要加载的实体类上,找到它的get方法,解决no-s ...