经常会有人被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. 【大数据】SparkSql 连接查询中的谓词下推处理 (二)

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/II48YxGfoursKVvdAXYbVg作者:李勇 目录:1.左表 join 后条件下推2.左表j ...

  2. Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现

    本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础. 为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是“Com ...

  3. WPF 鼠标移动时触发图片旋转(非动画)

    非动画,只是简单的触发器. 主要是针对旋转的写法. 代码 <Grid> <Image x:Name="image" Source="nifi3.gif& ...

  4. KVM virsh console

    (1) 查看正在运行的虚拟机 root@kvm:~# virsh list Id Name State ------------------------------------------------ ...

  5. 用guava快速打造两级缓存能力

    首先,咱们都有一共识,即可以使用缓存来提升系统的访问速度! 现如今,分布式缓存这么强大,所以,大部分时候,我们可能都不会去关注本地缓存了! 而在一起高并发的场景,如果我们一味使用nosql式的缓存,如 ...

  6. RSA应用指数与模生成公钥(ArcGIS Server)

    参考: https://www.cnblogs.com/luo30zhao/p/10515594.html https://blog.csdn.net/skiof007/article/details ...

  7. 基于OpenCV.Net连通域分析进行文本块分割

    上一次通过投影的方式进行了文本块分割,(见 https://www.cnblogs.com/BoyTNT/p/11812323.html )但这种方法有很大的局限性,要求分行清晰.不能有字符跨多行.不 ...

  8. SpringBoot+vue整合websocket

    0.引言 这里我先说下,网上对于websocket的解释有一堆不懂自己查,我这就不做原理解释,只上代码. 1.SpringBoot引入websocket maven 依赖 <dependency ...

  9. Dikstra 堆优化板子

    #include <bits/stdc++.h> #define MAXN 10005 using namespace std; typedef long long LL; vector& ...

  10. 别忘了在使用MES系统之前,还有关键一步!

    如果你是不熟悉工业自动化领域的专业人士,又或者是从IT或其他背景进入到操作技术(OT)领域的相关人士,那么我相信你不会后悔读到这篇文章. 我们都想做到智能化生产,想将MES系统,APS系统应用到生产过 ...