我在开发过程中遇到这么这个问题,因为赶进度,没有记下来处理方案,在鸟哥的博客看到原理分析,很到位!平时开发中总是急着处理问题,没有深入分析和记录问题。

1、问题:

今天是2018-07-31 执行代码:date("Y-m-d",strtotime("-1 month"))
输出是2018-06-01?

2、分析:

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

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

2-2、处理方案

  1. PHP5.3之后的版本处理方式
    ”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
    
  2. 使用mktime之类的, 把所有的日子忽略掉, 比如都限定为每月1号就可以了, 只不过就不如直接用first day来的更加优雅

参考资料:http://www.laruence.com/2018/...


双子城
46 声望6 粉丝

just do it!