今天正好7月31号。
我写了如下代码来获取上个月的开始时间:
$curTime = DateUtil::getCurrentDatetime();
$startTime = DateUtil::getCustomDatetime($curTime."-1 month", "Y-m-01 00:00:00"); //上个月开始时间
结果输出:2025-07-01 00:00:00
我期望的输出:2025-06-01 00:00:00
大致可以猜出,这就是date函数的工作思路:
今天7月31号,减去一个月就是6月31号,可实际6月并没有31号。
6月最大时间是30号,因此多了的一天,date函数会在6月30号的基础上再加1天,因此最后我们得到了:2025-07-01 00:00:00
时间上具有特殊性的,还有2月,我们正好可以拿2月来验证我上面的猜测。
在这个在线运行php的网页里,我写了如下代码:
$targetTime = '2025-03-30 12:00:00';
echo date("Y-m-d H:i:s", strtotime($targetTime." -1 month"));
执行结果是:2025-03-02 12:00:00
因为2025年2月最大天数是28天,所以3月30号减去一个月就是2月30号,相当于比实际多了2天。
然后date函数会把这2天加到2月的最后一天上,这样结果就是我们上面看到的那个时间了。
本文为翟码农个人博客下php分类里的原创文章,转载还请标注来源:http://www.zhai14.com/blog/a-tiny-tip-about-fetching-the-start-time-of-last-month-by-using-function-date.html
所以为了避免程序上因为时间条件有误带来的漏洞,所以我们要按照下面规则养成条件反射:
获取某个月份的开始时间,首先获取月份的第一天时间
每个月都有1号,就不会存在减1个月的结果出乎我们的意料。
所以文章一开始的需求,今天是7月31号,获取上个月的时间就可以通过如下代码来实现:
$curTime = DateUtil::getCurrentDatetime();
$curMonthFirstDayDate = DateUtil::getCustomDatetime($curTime, "Y-m-01 00:00:00"); //当月第一天
$startTime = DateUtil::getCustomDatetime($curMonthFirstDayDate."-1 month", "Y-m-01 00:00:00"); //上个月开始时间
昨天8月1日,系统的最近24小时的功率折线图变空白了。
产生这个bug,说来也巧,跟业务也有些微的关系。
业务:
电能数据是通过第三方系统提供的http接口采集的。但这个第三方系统有时会出故障,这时候用户希望大屏这边能够用上个月同一时间的功率数据来替代。
(其实个人感觉功率数据也没啥意义,就是免得老板带客户参观,看到大屏折线图空白不太好)
说这个bug出现的巧,这不,正好第三方系统出故障了,所以进入了上面的业务逻辑。
bug就产生于我下面这段php代码:
if($isAbnormal){
//异常情况下,抓上个月同一时间的数据
$startTime = DateUtil::getCustomDatetime($startTime."-1 month");
$endTime = DateUtil::getCustomDatetime($endTime."-1 month");
$powerDataList = $this->getEquipmentHistoryWithNoPage($deviceId, $startTime, $endTime);
}else{
$powerDataList = $this->getEquipmentHistoryWithNoPage($deviceId, $startTime, $endTime);
}
接下来我就通过数据举例子来说明吧:
昨天展示的折线图数据时间段,大概是2025-07-31 10:00:00到2025-08-01 10:00:00(方便描述,这里我就具体到10点)。
我以为时间区间的开始时间和结束时间,都减1个月就是上个月的同一时间区间。
逻辑上没问题,但程序上如果像我上面那样实现就有问题了。
到这里,大家应该明白了吧。如果还没明白,建议把本篇文章再看一遍。