<?php
// 定义常量
define('SATURDAY', 6); // 星期六对应的数字
define('SUNDAY', 7); // 星期日对应的数字
// 假期数组,包含需要排除的日期
$holidays = [
'2024-01-01', // 元旦
// '2024-02-10', // 春节
// '2024-02-11',
'2024-02-12',
'2024-02-13',
'2024-02-14',
'2024-02-15',
'2024-02-16',
// '2024-02-17',
'2024-04-04', // 清明节
'2024-04-05',
// '2024-04-06',
'2024-05-01', // 劳动节
'2024-05-02',
'2024-05-03',
// '2024-05-04',
// '2024-05-05',
// '2024-06-08', // 端午节
// '2024-06-09',
'2024-06-10',
// '2024-09-15', // 中秋节
'2024-09-16',
'2024-09-17',
'2024-10-01', // 国庆节
'2024-10-02',
'2024-10-03',
'2024-10-04',
// '2024-10-05',
// '2024-10-06',
'2024-10-07',
// 其他节日或假期
];
// 周六补班日期数组
$weekendWorkdays = [
'2024-05-11', // 补班劳动节
'2024-09-14', // 补班中秋节
'2024-10-12', // 补班国庆节
// 其他周六补班日期
];
// 周日补班日期数组
$sundayWorkdays = [
'2024-02-04', // 补班春节
'2024-02-18', // 补班春节
'2024-04-07', // 补班清明节
'2024-04-28', // 补班劳动节
'2024-09-29', // 补班国庆节
// 其他周日补班日期
];
// 时间间隔
$dateInterval = DateInterval::createFromDateString('1 day');
/**
* 计算指定日期之后的工作日日期
*
* @param string $startDate 起始日期,格式为 YYYY-MM-DD
* @param int $daysToAdd 需要添加的工作日天数
* @param array $holidays 假期数组,包含需要排除的日期
* @param array $weekendWorkdays 周六补班日期数组
* @param array $sundayWorkdays 周日补班日期数组
* @return string 最终的工作日日期,格式为 YYYY-MM-DD
*/
function addWorkingDays($startDate, $daysToAdd, $holidays, $weekendWorkdays, $sundayWorkdays)
{
// 将起始日期转换为时间戳
$startTimestamp = strtotime($startDate);
while ($daysToAdd > 0) {
// 将时间戳转换为日期字符串
$dateString = date('Y-m-d', $startTimestamp);
// 获取星期几
$dayOfWeek = date('N', $startTimestamp);
if ($dayOfWeek >= SATURDAY) { // 周六和周日
// 检查是否为周六补班日期
if (isset($weekendWorkdays[$dateString])) {
$daysToAdd--;
}
// 检查是否为周日补班日期
elseif (isset($sundayWorkdays[$dateString])) {
$daysToAdd--;
}
} elseif (isset($holidays[$dateString])) { // 假期
// do nothing
} else {
$daysToAdd--;
}
// 时间戳加上一天
$startTimestamp += 86400;
}
// 将时间戳转换为日期字符串
return date('Y-m-d', $startTimestamp - 86400);
}
// 示例用法
$startDate = '2024-02-01';
$daysToAdd = 9;
$resultDate = addWorkingDays($startDate, $daysToAdd, array_flip($holidays), array_flip($weekendWorkdays), array_flip($sundayWorkdays));
echo "结果日期:$resultDate";
第二中写法
<?php
// 定义常量
define('SATURDAY', 6); // 星期六对应的数字
define('SUNDAY', 7); // 星期日对应的数字
// 假期数组,包含需要排除的日期,使用array_flip预处理以便快速检查
$holidays = array_flip([
'2024-01-01', // 元旦
// '2024-02-10', // 春节
// '2024-02-11',
'2024-02-12',
'2024-02-13',
'2024-02-14',
'2024-02-15',
'2024-02-16',
// '2024-02-17',
'2024-04-04', // 清明节
'2024-04-05',
// '2024-04-06',
'2024-05-01', // 劳动节
'2024-05-02',
'2024-05-03',
// '2024-05-04',
// '2024-05-05',
// '2024-06-08', // 端午节
// '2024-06-09',
'2024-06-10',
// '2024-09-15', // 中秋节
'2024-09-16',
'2024-09-17',
'2024-10-01', // 国庆节
'2024-10-02',
'2024-10-03',
'2024-10-04',
// '2024-10-05',
// '2024-10-06',
'2024-10-07',
// 其他节日或假期
]);
// 周六补班日期数组,使用array_flip预处理以便快速检查
$weekendWorkdays = array_flip([
'2024-05-11', // 补班劳动节
'2024-09-14', // 补班中秋节
'2024-10-12', // 补班国庆节
// 其他周六补班日期
]);
// 周日补班日期数组,使用array_flip预处理以便快速检查
$sundayWorkdays = array_flip([
'2024-02-04', // 补班春节
'2024-02-18', // 补班春节
'2024-04-07', // 补班清明节
'2024-04-28', // 补班劳动节
'2024-09-29', // 补班国庆节
// 其他周日补班日期
]);
/**
* 计算指定日期之后的工作日日期
*/
function addWorkingDays($startDate, $daysToAdd, $holidays, $weekendWorkdays, $sundayWorkdays)
{
$date = new DateTime($startDate);
while ($daysToAdd > 0) {
$dateString = $date->format('Y-m-d');
$dayOfWeek = (int)$date->format('N');
// 检查是否是工作日(包括周六、周日补班,且不是假期)
if (!isset($holidays[$dateString]) &&
(($dayOfWeek < SATURDAY) || isset($weekendWorkdays[$dateString]) || isset($sundayWorkdays[$dateString]))) {
// 如果是工作日,则减少天数
$daysToAdd--;
}
// 如果还需要添加工作日,才增加日期
if ($daysToAdd > 0) {
$date->add(new DateInterval('P1D'));
}
}
return $date->format('Y-m-d');
}
// 示例用法
$startDate = '2024-02-01';
$daysToAdd = 9;
$resultDate = addWorkingDays($startDate, $daysToAdd, $holidays, $weekendWorkdays, $sundayWorkdays);
echo "结果日期:$resultDate";