我目前正在处理一个项目(会员制(,该项目有开始日期和截止日期。例如,用户选择了30天会员资格,其开始日期为2022年9月5日。因此,2022年5月9日+30天等于到期日。但我想跳过星期天,在开始日期加上30天。我如何在PHP中做到这一点?
编辑:对不起,我是一个工程师,我尝试了你所有的推荐,但与我想要的不匹配。这些是我计算过期日期的代码。
date_default_timezone_set('Asia/Manila');
$startDate = date('Y-m-d');
$many_days = 30;//the value of this comes from database but let's assume that its 30
$expireDate = date('Y-m-d', strtotime('+'.$many_days.' day'));//expiredate
我会使用一个循环。如果你打算把它扩展到假期,这也是一个很好的开始。否则,这太夸张了,但我真的不认为你会遇到性能问题。
所以我们开始了:
$start_date = "2022-09-05";
$start = new DateTime($start_date);
$days = 30;
while ($days) {
// P1D means a period of 1 day
$start->add(new DateInterval('P1D'));
$day = $start->format('N');
// 7 = sunday
if ($day != 7) {
$days--;
}
}
print_r($start);
// output:
// [date] => 2022-10-10 00:00:00.000000
为了获得更好的性能,应该预先计算完整的周数。以下函数允许您命名一周中未计算的一天或多天。
/**
* Add days without specific days of the week
*
* @param DateTime $startDate start Date
* @param int $days number of days
* @param array $withoutDays array with elements "Mon", "Tue", "Wed", "Thu", "Fri", "Sat","Sun"
* @return DateTime
*/
function addDaysWithout(DateTime $startDate ,int $days, array $withoutDays = []) : DateTime
{
//validate $withoutDays
$validWeekDays = 7 - count($withoutDays);
$validIdentifiers = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat","Sun"];
if($validWeekDays <= 0 OR
$withoutDays != array_intersect($withoutDays,$validIdentifiers)){
$msg = 'Invalid Argument "'.implode(',',$withoutDays).'" in withoutDays';
throw new InvalidArgumentException($msg);
}
$start = clone $startDate;
$fullWeeks = (int)($days/$validWeekDays)-1;
if($fullWeeks > 0){
$start ->modify($fullWeeks.' weeks');
$days -= $fullWeeks * $validWeekDays;
}
while($days){
$start->modify('+1 Day');
if(!in_array($start->format('D'),$withoutDays)){
--$days;
}
}
return $start;
}
应用示例:
$start = date_create('2022-09-05');
$dt = addDaysWithout($start,30,["Sun"]);
var_dump($dt);
//object(DateTime)#3 (3) { ["date"]=> string(26) "2022-10-10 00:00:00.000000"
$start = date_create('2022-09-05');
$dt = addDaysWithout($start,30,["Mon","Sun"]);
var_dump($dt);
//object(DateTime)#3 (3) { ["date"]=> string(26) "2022-10-15
演示:https://3v4l.org/AZX0E