PHP中日期数组查询及递归调整到期前置日期的实现问询
PHP 日期处理功能实现
没问题,这两个PHP日期相关的功能我帮你搞定了,直接上代码和清晰的说明:
1. 在日期数组中搜索指定日期
这个功能的关键是统一日期格式的比较,避免因为字符串格式差异(比如大小写、分隔符)导致匹配失败,最好的方式是转换成时间戳来对比:
function searchDateInArray($dateArray, $targetDate, $dateFormat = 'd-M-Y') { // 将目标日期转换为时间戳,确保格式统一 $targetTimestamp = DateTime::createFromFormat($dateFormat, $targetDate)?->getTimestamp(); if (!$targetTimestamp) { throw new InvalidArgumentException('目标日期格式不正确'); } foreach ($dateArray as $date) { $currentTimestamp = DateTime::createFromFormat($dateFormat, $date)?->getTimestamp(); if ($currentTimestamp === $targetTimestamp) { return true; // 找到匹配日期,返回true // 如果你需要返回数组中的对应元素或索引,可以改成: // return $date; // 或者 return array_search($date, $dateArray); } } return false; // 未找到匹配日期 } // 使用示例 $sampleDates = ['26-Oct-2017', '20-Oct-2017', '18-Oct-2017']; $searchTarget = '20-Oct-2017'; var_dump(searchDateInArray($sampleDates, $searchTarget)); // 输出 bool(true)
说明
- 用
DateTime::createFromFormat解析日期,避免手动处理字符串的麻烦 - 时间戳对比是最可靠的日期匹配方式,不受格式细节影响
- 加入了格式校验,防止传入无效日期导致错误
2. 计算到期前指定天数并递归调整节假日
这个功能需要先计算初始日期,然后递归检查是否为节假日,直到找到第一个非节假日的日期:
function getAdjustedExpiryDate($expiryDateStr, $daysBefore, $holidayArray, $inputFormat = 'd-M-Y', $outputFormat = 'd-m-Y') { // 初始化到期日期对象 $expiryDate = DateTime::createFromFormat($inputFormat, $expiryDateStr); if (!$expiryDate) { throw new InvalidArgumentException('到期日期格式不正确'); } // 计算初始目标日期:到期日往前推指定天数 $targetDate = (clone $expiryDate)->sub(new DateInterval("P{$daysBefore}D")); // 将节假日数组转换为时间戳集合,提升查找效率 $holidayTimestamps = array_map(function($holiday) use ($inputFormat) { $holidayDate = DateTime::createFromFormat($inputFormat, $holiday); return $holidayDate ? $holidayDate->getTimestamp() : null; }, $holidayArray); $holidayTimestamps = array_filter($holidayTimestamps); // 过滤无效日期 // 递归调整日期的闭包函数 $adjustDate = function($date) use (&$adjustDate, $holidayTimestamps, $outputFormat) { $dateTimestamp = $date->getTimestamp(); if (in_array($dateTimestamp, $holidayTimestamps)) { // 当前日期是节假日,往前推1天继续检查 $adjustedDate = (clone $date)->sub(new DateInterval('P1D')); return $adjustDate($adjustedDate); } else { // 返回符合格式的非节假日日期 return $date->format($outputFormat); } }; return $adjustDate($targetDate); } // 使用示例(完全匹配你给出的场景) $distinct_expiries = '26-Oct-2017'; $time_to_expiry = 6; $trading_holiday_array = ['20-Oct-2017', '19-Oct-2017']; $result = getAdjustedExpiryDate($distinct_expiries, $time_to_expiry, $trading_holiday_array); echo $result; // 输出:18-10-2017
说明
- 使用
clone复制DateTime对象,避免修改原到期日期 - 把节假日转换成时间戳集合,
in_array查找更高效 - 递归逻辑自动处理连续节假日的情况(比如示例中20号和19号都是节假日,自动调整到18号)
- 加入了格式校验,确保输入日期有效
内容的提问来源于stack exchange,提问作者Rusty Banks
相关产品推荐
相关产品推荐

