看现象
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")))); |
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("last day of -1 month", strtotime("2017-03-31")))); |
如果使用 Carbon\Carbon
可以用 subMonthNoOverflow
与 addMonthNoOverflow
防止进位:
Carbon::parse('2020-03-31')->subMonthNoOverflow()->toDateString(); |
Ym 类似问题
在当日是 31 号场景下:
Carbon::createFromFormat('Ym', '202206')->format('Y-m'); |
!
Resets all fields (year, month, day, hour, minute, second, fraction and timezone information) to zero-like values ( 0 for hour, minute, second and fraction, 1 for month and day, 1970 for year and UTC for timezone information)
Without !, all fields will be set to the current date and time.
如果 format 包含字符 !,则未在 format 中提供的生成日期/时间部分以及 ! 左侧的值将设置为 Unix 纪元的相应值。
The Unix epoch is 1970-01-01 00:00:00
UTC.
Carbon::createFromFormat('!Ym', '202206')->format('Y-m'); |
References
– EOF –