看现象
var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2020-07-31"))));
var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2020-05-31"))));
var_dump(date("Y-m-d", strtotime("-1 month", strtotime("2020-02-29"))));
var_dump(date("Y-m-d", strtotime("-1 month", strtotime("2020-03-31"))));
Carbon::parse("2020-07-31")->addMonth()->toDateString();
Carbon::parse("2020-05-31")->addMonth()->toDateString();
Carbon::parse("2020-02-29")->subMonth()->toDateString();
Carbon::parse("2020-03-31")->subMonth()->toDateString();
|
原因
var_dump(date("Y-m-d", strtotime("+1 month", strtotime("2020-05-31"))));
|
date 内部的处理逻辑:
2020-05-31
做 +1 month
也就是 2020-06-31
。- 再做日期规范化,因为没有
06-31
,所以 06-31
就等于了 07-01
。
var_dump(date("Y-m-d", strtotime("2020-06-31")));
var_dump(date("Y-m-d", strtotime("next month", strtotime("2017-01-31"))));
var_dump(date("Y-m-d", strtotime("last month", strtotime("2017-03-31"))));
|
解决方案
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime("2017-03-31"))));
var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime("2017-08-31"))));
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime("2017-03-01"))));
|
如果使用 Carbon\Carbon
可以用 subMonthNoOverflow
与 addMonthNoOverflow
防止进位:
Carbon::parse('2020-03-31')->subMonthNoOverflow()->toDateString();
Carbon::parse("2020-05-31")->addMonthNoOverflow()->toDateString();
|
References
– EOF –