今天遇见一个问题,那就是有一个vip会员功能,购买1个月,3个月,6个月VIP。然后我们需要给用户更新vip的过期时间,但是客户端和服务端的时间始终不一致。
首先,网上一大堆的增加月份的例子都是如下:
echo date(“Y-m-d”, strtotime(“2017-01-31 +3 month”)); PHP结果:2017-05-01
咋一看其实没什么不对,但是下面的例子就有点让我们吐血了。
echo date(“Y-m-d”, strtotime(“2017-01-31 +1 month”)); PHP结果:2017-03-03 客户端(IOS/Android)结果:2017-02-28
echo date(“Y-m-d”, strtotime(“2017-01-30 +1 month”)); PHP结果:2017-03-02 客户端(IOS/Android)结果:2017-02-28
echo date(“Y-m-d”, strtotime(“2017-02-01 +1 month”)); PHP结果:2017-03-01 客户端(IOS/Android)结果:2017-03-01
echo date(“Y-m-d”, strtotime(“2017-02-02 +1 month”)); PHP结果:2017-03-02 客户端(IOS/Android)结果:2017-03-02
这里是不是就很难接受了?最主要是ios和android都不是这样的。没办法,为了满足客户端的逻辑,只有自己重写写了一个函数,代码如下:
/**
* 根据传递的时间错,加减月份,获取之后的时间。
* 1.31 +1 month应该是2月最后一天, 2.1 +1 month应该是3.1
*
* @param string $calcStr (+/- 1 month),计算月份,加减月份
* @param int $timestamp 需要计算的时间戳
* @param string $format 时间输出格式
*
* @return false|int|string
*/
public static function calcMonthDay($calcStr, $timestamp = 0, $format = 'Y-m-d')
{
if (!$timestamp) {
$timestamp = time();
}
if (!is_integer($timestamp)) {
return $timestamp;
}
//记录需要计算的当前的天数和具体时间
$day = date("d", $timestamp);
$time = date("H:i:s", $timestamp);
//划算成月份,通过月份首先递增月份
$timestampMonth = date("Y-m", $timestamp);
$monthCalcTime = strtotime($timestampMonth . ' ' . $calcStr . " month");
//获取计算后的年月
$calcYear = date("Y", $monthCalcTime);
$calcMonth = date("m", $monthCalcTime);
//获取计算的月份的实际天数
$calcDay = date("t", $monthCalcTime);
//如果计算的天数大于计算的天数,则取当前计算的天数,否则使用计算后的天数
if ($calcDay > $day) {
$calcDay = $day;
}
//组合计算后的日期时间
$calcDateTime = "$calcYear-$calcMonth-$calcDay $time";
//格式化日期时间
$calcTime = date($format, strtotime($calcDateTime));
return $calcTime;
}
这就计算出来的结果就满足了客户端的需求,看起来也比较正常。