php strtotime,mktime,DateTime函数处理时间累加问题

时间戳(年月日时分秒)  使用strtotime函数,结合+1 month,-1 month,next month,last month的时候会出现一些问题.

demo示例:

1 //时间"2018-10-16 12:00:00"增加一个月
2 $timeOne = strtotime("2018-10-16 12:00:00");
3 echo date("Y-m-d H:i:s", strtotime("+ 1 month", $timeOne ));//2018-10-16 12:00:00[正确]
4  
5 //时间"2018-10-31 10:00:00"增加一个月
6 $timeTwo = strtotime("2018-10-31 12:00:00");
7 echo date("Y-m-d H:i:s", strtotime("+ 1 month", $timeTwo ));//2018-12-01 12:00:00[错误]

"date"内部逻辑的处理,其实是正确. 解析内部处理的逻辑?

1 (1): 先做+1 month,假设当前时间为10-31, 增加一个月时间为11-31
2 (2): 再做日期规范化,因为11月没有31日,所以就好像3点60等于4点一样;11月31日就等于12月1日

解决方法一: PHP>=5.3  date新增修正短语,用来明确这个问题,那就是"first day of" 和 "last day of",可以限定不要让date自动"规范化"

1 echo date("Y-m-d H:i:s", strtotime("last day of +1 month", strtotime("2018-10-31 12:00:00")));//2018-11-30 12:00:00[正确]

解决方法二: mktime  获取当前时间: date("Y-m-d H:i:s", mktime(date('H'),date('i') ,date('s'), date('m'), date('d'), date('Y')))

1 //设定时间"2018-10-31 12:00:00"
2 echo date("Y-m-d H:i:s", mktime(date('12'),0, 0, date('10'), date('31'), date('2018')));
3 
4 //指定增加30天,时间"2018-11-30 12:00:00"
5 echo date("Y-m-d H:i:s", mktime(date('12'),0, 0, date('10'), date('31')+30, date('2018')));//2018-11-30 12:00:00[正确]

解决方法三: (PHP 5 >= 5.2.0, PHP 7)  DateTime

 1 <?php
 2 //设定初始时间: 'Y-m-d H:i:s'
 3 $dateTime = new DateTime("2018-10-31 12:00:00");
 4 
 5 $addMonth = 1; //设定间隔的月份
 6 
 7 //初始时间的天数值
 8 $initDay = $dateTime->format("d");   
 9 
10 //DateInterval构造函数的参数是一个表示时间间隔约定的字符串,这个时间间隔约定以字母P开头,后面跟着一个整数,最后是一个周期标识符,限定前面的整数.
11 //有效周期标识符如下: Y(年) M(月) D(日) W(周) H(时) M(分) S(秒) 间隔约定中既可以有时间也可以有日期,如果有时间需要在日期和时间之间加上字母"T"用来分隔.
12 //例如: 间隔约定P2D表示间隔两天; 间隔约定P2DT5H2M表示间隔两天五小时两分钟
13 
14 $dateTime->add(new DateInterval("P" . $addMonth . "M"));//增加 一个月时间;  2018-12-01 12:00:00[错误]
15 
16 $newDay = $dateTime->format("d");//累加后新的日期的天数值
17 
18 //判断间隔月份,天数值是否相同
19 if($initDay != $newDay) {
20     //不同减去差值
21     $dateTime->sub(new DateInterval("P" . $newDay . "D"));//减去 新初时间,天数差的值
22 }
23 
24 echo $initDay;//31(天)
25 echo "<br>";
26 echo $newDay;//1(天)
27 echo "<br>";
28 echo $dateTime->format("Y-m-d H:i:s");//2018-11-30 12:00:00[正确]
原文地址:https://www.cnblogs.com/cxx8181602/p/9664632.html