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

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




												

最新文章

  1. 微信JSAPI支付
  2. Windows下Python中pip安装Pillow报错总结(转载)
  3. P1905生活大爆炸版 石头剪刀布
  4. iOS开发UI篇—iOS开发中三种简单的动画设置
  5. Inside The C++ Object Model - 03
  6. bean中集合属性的配置
  7. Centos后台运行jar
  8. SICP 练习 1.3
  9. Poj 2371 Questions and answers(排序)
  10. ZOJ 3635 Cinema in Akiba(线段树)
  11. memcache总结
  12. 【Linux】查看系统信息
  13. 【应知应会】15个常用的JavaScript字符串操作方法
  14. MySQL 连接出现 Authentication plugin 'caching_sha2_password' cannot be loaded
  15. python网络爬虫笔记(五)
  16. GMA Round 1 双曲线与面积
  17. c# 导出表格
  18. Go linux 实践3
  19. 如何关闭Golang中的HTTP连接 How to Close Golang's HTTP connection
  20. HTML 标签大全及属性

热门文章

  1. Centos6安装oracle10g
  2. java面试题之----转发(forward)和重定向(redirect)的区别
  3. JS实现“双色球”
  4. java实现多文件上传01
  5. # putty的使用和保存配置
  6. 推荐一个很好用的脚本session snapper
  7. jsp页面传输到xxAction.java乱码解决
  8. 最简单的docker教程:在docker里运行nginx服务器
  9. IOS 播放视频(MPMoviePlayerController、MPMoviePlayerViewController)
  10. { ($0, Resolver($0.box)) }(Promise<T>(.pending)):闭包的定义与执行合一