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

今天是2018-08-31 执行代码:

  1. date("Y-m-d",strtotime("+1 month"))

怎么输出是2018-10-01?

虽然这个问题看起来很迷惑, 但从内部逻辑上来说呢, 其实是”对”的
date内部的对于这种事情的处理逻辑:

  1. 先做-1 month, 那么当前是07-31, 减去一以后就是06-31.
  2. 再做日期规范化, 因为6月没有31号, 所以就好像2点60等于3点一样, 6月31就等于了7月1

是不是逻辑很”清晰”呢? 我们也可以手动验证第二个步骤, 比如:

  1. var_dump(date("Y-m-d", strtotime("2017-06-31")));
  2. //输出2017-07-01

也就是说, 只要涉及到大小月的最后一天, 都可能会有这个迷惑, 我们也可以很轻松的验证类似的其他月份, 印证这个结论:

  1. var_dump(date("Y-m-d", strtotime("-1 month", strtotime("2017-03-31"))));
  2. //输出2017-03-03
  3. var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2017-08-31"))));
  4. //输出2017-10-01
  5. var_dump(date("Y-m-d", strtotime("next month", strtotime("2017-01-31"))));
  6. //输出2017-03-03
  7. var_dump(date("Y-m-d", strtotime("last month", strtotime("2017-03-31"))));
  8. //输出2017-03-03

那怎么办呢?

从PHP5.3开始呢, date新增了一系列修正短语, 来明确这个问题, 那就是”first day of” 和 “last day of”, 也就是你可以限定好不要让date自动”规范化”:

  1. var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime("2017-03-31"))));
  2. //输出2017-02-28
  3. var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime("2017-08-31"))));
  4. ////输出2017-09-01
  5. var_dump(date("Y-m-d", strtotime("first day of next month", strtotime("2017-01-31"))));
  6. ////输出2017-02-01
  7. var_dump(date("Y-m-d", strtotime("last day of last month", strtotime("2017-03-31"))));
  8. ////输出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')吗的更多相关文章

  1. php: +1天, +3个月, strtotime(): +1 day, +3 month

    php: +1天, +3个月, strtotime():  +1 day, +3 month 比如,我现在当前时间基础上+1天: strtotime("+1 day"); 比如我现 ...

  2. 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: ...

  3. 时间函数 date strtotime

    date_default_timezone_set('Asia/Shanghai');echo strtotime('Today');echo strtotime(date('Y-m-d')); 获取 ...

  4. php strtotime 和 date 日期操作

    time()得到的数值是1970-1-1到现在的秒数,strtotime("now")也是,两个值是相同的. http://doc.thinkphp.cn/manual/syste ...

  5. PHP中的strtotime()对于31日求上个月有问题

    原文出处 <?php $date = "2012-07-31"; $date_unix = strtotime($date); $lastmonth = strtotime( ...

  6. 谨慎使用php的strtotime()函数

    我们在日常业务中,针对业务量,经常会采用对数据库按时间做横向分表,分表后的查询往往会涉及到时间问题.例如,我们想查询某个用户距离当前时间1个月的订单情况,在这个时候,我们有些会用到strtotime( ...

  7. strtotime的几种用法区别

    strtotime不仅可以使用类似Y-m-d此类标准的时间/日期字符串来转化时间戳, 还可以用类似自然语言的来生成时间戳, 类似: strtotime('last day'); strtotime(' ...

  8. strtotime 获取之前,之后时间

    一年之前 <?php echo strtotime('-1 year'); ?> 一年之后 <?php echo strtotime('+1 year'); ?> 一月之前 & ...

  9. [PHP] 重回基础(date函数和strtotime函数)

    date():格式化一个本地时间或者日期,当前时间 2016年5月13日 15:19:49 使用函数date(),输出当前是月份中的第几天,参数:String类型 d 例如:echo date(&qu ...

随机推荐

  1. sierpinski垫片(3D)[误]

    今天是因为可以用py而高兴的一天. 昨天老板淡淡地回了一句,sierpinski地毯画得挺好的. 我思考了五秒钟之后,想起来作业其实是sierpinski垫片.     三角垫片比地毯难做多了. 因为 ...

  2. 如何安装redis

    主要方式有四种:1.使用 Docker 安装.2.通过 Github 源码编译.3.直接安装 apt-get install(Ubuntu).yum install(RedHat) 或者 brew i ...

  3. java构建树形列表(带children属性)

    一些前端框架提供的树形表格需要手动构建树形列表(带children属性的对象数组),这种结构一般是需要在Java后台构建好. 构建的方式是通过id字段与父id字段做关联,通过递归构建children字 ...

  4. Logstash:多个配置文件(conf)

    Logstash:多个配置文件(conf) 对于多个配置的处理方法,有多个处理方法: 多个pipeline 一个pipleline处理多个配置文件 一个pipeline含有一个逻辑的数据流,它从inp ...

  5. MySQL分析数据运行状态利器【show full processlist】

    原文地址:https://www.cnblogs.com/shihuc/p/8733460.html 今天的主角是: SHOW [FULL] PROCESSLIST show full process ...

  6. SAP-简单的OALV演示练习

    接上一篇传统ALV:https://www.cnblogs.com/BruceKing/p/11320165.html. 首先介绍下什么是ALV,在R/3 4.6C之前ALV全称为ABAP List ...

  7. 最全面的PS快捷键使用指南(图文演示)

    每次做图的时候都会记错快捷键,很苦恼有木有!!!只能各处搜寻PS快捷键汇总起来,老板再也不会说我作图慢了....... 1.Ctrl+T:自由变形 该快捷键,主要对图层进行旋转.缩放等变形调整,同时可 ...

  8. python之三方库(冷门+热门)

    AES加密库 pycryptodome

  9. spring cloud 框架源码 activiti工作流 vue.js html 跨域 前后分离 springboot

    1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...

  10. 为什么重复的GET请求变慢了?

    最近在研究慢请求监控的问题,写了一个简单的测试代码:在网页端(index.html)通过fetch函数向服务端获取数据,然后打印请求耗时. function requestData() { let s ...