中国节假日功能解析:zjkal/time-helper 的 ChinaHoliday 类
本文详细解析了 zjkal/time-helper 库中的 ChinaHoliday 类,该类是专门用于处理中国节假日逻辑的核心组件。文章从设计目标、判断逻辑、实际应用案例以及与其他时间功能的结合使用四个方面展开,全面介绍了该类的功能与实现方式。
ChinaHoliday 类的设计目标
ChinaHoliday 类是 zjkal/time-helper 库中专门用于处理中国节假日逻辑的核心组件。它的设计目标是为开发者提供一个高效、准确且易于集成的工具,用于判断特定日期是否为中国的法定节假日或工作日。以下是其设计目标的具体解析:
1. 精准的节假日判断
ChinaHoliday 类的首要目标是提供精准的节假日判断功能。它通过维护两个静态数组 $holiday 和 $workday,分别存储每年的节假日和调休日数据。这些数据基于中国官方发布的节假日安排,确保判断结果的准确性。
classDiagram
class ChinaHoliday {
-static $holiday: array
-static $workday: array
+static isWorkday($datetime): bool
+static isHoliday($datetime): bool
}
2. 灵活的日期输入支持
为了适应不同的使用场景,ChinaHoliday 类支持多种日期输入格式:
- 时间戳(如
1735660800) - 日期字符串(如
2025-01-01 00:00:00) - 默认当前时间
这种灵活性使得开发者可以轻松集成到现有系统中,无需额外的日期格式转换逻辑。
3. 高效的逻辑实现
ChinaHoliday 类的核心逻辑通过两个方法实现:
isWorkday:判断是否为工作日。isHoliday:判断是否为节假日。
其内部逻辑通过以下步骤实现:
- 提取日期的年份和月份日信息(
Y和md)。 - 检查是否为周末或调休日。
- 结合节假日数据返回判断结果。
flowchart TD
A[输入日期] --> B{是否为工作日?}
B -->|是| C[返回 True]
B -->|否| D[返回 False]
4. 易于维护和扩展
ChinaHoliday 类的设计注重可维护性:
- 静态数组
$holiday和$workday按年份组织,便于更新。 - 逻辑清晰,便于后续扩展(如支持更多年份或自定义节假日)。
5. 与 TimeHelper 的无缝集成
ChinaHoliday 类依赖于 TimeHelper 类进行日期格式化,这种设计避免了重复造轮子,同时也确保了日期处理的一致性。
通过以上设计目标,ChinaHoliday 类为开发者提供了一个强大且易用的工具,满足了中国节假日判断的多样化需求。
工作日与节假日的判断逻辑
在中国,节假日和工作日的安排往往较为复杂,尤其是调休和法定假日的存在,使得简单的周末判断无法满足需求。ChinaHoliday 类通过预定义的节假日和调休日数据,结合时间判断逻辑,提供了精准的工作日和节假日判断功能。
核心逻辑解析
ChinaHoliday 类的工作日和节假日判断逻辑基于以下两个核心条件:
-
是否为工作日:
- 如果日期是平常日(周一至周五),并且该日期不在预定义的节假日列表中,则判定为工作日。
- 如果日期是周末(周六或周日),但在预定义的调休日列表中,则判定为工作日。
-
是否为节假日:
- 直接通过
!isWorkday()方法判断,即非工作日即为节假日。
- 直接通过
代码实现
以下是 isWorkday 和 isHoliday 方法的实现逻辑:
public static function isWorkday($datetime = null): bool
{
$y = TimeHelper::format('Y', $datetime);
$md = TimeHelper::format('md', $datetime);
// 条件1:平常日且非节假日
$condition1 = TimeHelper::isWeekday($datetime) && (!array_key_exists($y, self::$holiday) || !in_array($md, self::$holiday[$y]));
// 条件2:周末且为调休日
$condition2 = TimeHelper::isWeekend($datetime) && array_key_exists($y, self::$workday) && in_array($md, self::$workday[$y]);
return $condition1 || $condition2;
}
public static function isHoliday($datetime = null): bool
{
return !self::isWorkday($datetime);
}
流程图展示
以下是通过流程图展示的判断逻辑:
flowchart TD
A[开始] --> B{是否为平常日?}
B -- 是 --> C{是否在节假日列表中?}
C -- 否 --> D[判定为工作日]
C -- 是 --> E[判定为节假日]
B -- 否 --> F{是否在调休日列表中?}
F -- 是 --> D
F -- 否 --> E
数据存储
ChinaHoliday 类通过静态属性 $holiday 和 $workday 存储节假日和调休日数据,格式如下:
private static $holiday = [
'2025' => ['0101', '0128', '0129', '0130', '0131', '0203', '0204', '0404', '0501', '0502', '0505', '0602', '1001', '1002', '1003', '1006', '1007', '1008'],
];
private static $workday = [
'2025' => ['0126', '0208', '0427', '0928', '1011'],
];
示例测试
通过单元测试验证逻辑的正确性:
public function testIsWorkday()
{
$this->assertFalse(ChinaHoliday::isWorkday('2025-01-01')); // 元旦假期
$this->assertTrue(ChinaHoliday::isWorkday('2025-01-26')); // 调休工作日
}
public function testIsHoliday()
{
$this->assertTrue(ChinaHoliday::isHoliday('2025-01-01')); // 元旦假期
$this->assertFalse(ChinaHoliday::isHoliday('2025-01-26')); // 调休工作日
}
表格说明
以下是节假日和调休日的示例数据表格:
| 年份 | 节假日(示例) | 调休日(示例) |
|---|---|---|
| 2025 | 0101, 0128, 0129 | 0126, 0208 |
| 2024 | 0101, 0212, 0213 | 0204, 0218 |
通过以上逻辑和示例,开发者可以轻松理解并应用 ChinaHoliday 类的工作日和节假日判断功能。
实际应用案例与示例代码
ChinaHoliday 类提供了便捷的方法来判断国内节假日和工作日,适用于多种实际场景。以下是一些典型的应用案例和示例代码,帮助开发者快速理解和使用该功能。
1. 判断特定日期是否为工作日或节假日
以下代码展示了如何使用 isWorkday 和 isHoliday 方法判断特定日期是否为工作日或节假日:
// 判断 2023 年 10 月 1 日是否为节假日
$isHoliday = ChinaHoliday::isHoliday('2023-10-01');
echo $isHoliday ? '是节假日' : '不是节假日'; // 输出:是节假日
// 判断 2023 年 10 月 7 日是否为工作日
$isWorkday = ChinaHoliday::isWorkday('2023-10-07');
echo $isWorkday ? '是工作日' : '不是工作日'; // 输出:不是工作日
2. 批量检查日期列表
如果需要检查多个日期是否为工作日或节假日,可以结合循环和数组操作:
$dates = ['2023-01-01', '2023-05-01', '2023-10-01'];
foreach ($dates as $date) {
$result = ChinaHoliday::isHoliday($date) ? '节假日' : '工作日';
echo "$date 是 $result\n";
}
输出结果:
2023-01-01 是 节假日
2023-05-01 是 节假日
2023-10-01 是 节假日
3. 结合时间戳使用
ChinaHoliday 类支持时间戳作为输入参数,适用于动态生成的时间:
$timestamp = strtotime('2023-12-31');
$isHoliday = ChinaHoliday::isHoliday($timestamp);
echo $isHoliday ? '是节假日' : '不是节假日'; // 输出:不是节假日
4. 动态更新节假日数据
ChinaHoliday 类的节假日数据存储在静态属性 $holiday 和 $workday 中。开发者可以根据需要动态更新这些数据:
// 添加 2025 年的节假日数据
ChinaHoliday::$holiday['2025'] = ['0101', '0128', '0130', '1001', '1002'];
ChinaHoliday::$workday['2025'] = ['0126', '0208'];
// 验证更新后的数据
$isHoliday = ChinaHoliday::isHoliday('2025-01-28');
echo $isHoliday ? '是节假日' : '不是节假日'; // 输出:是节假日
5. 结合其他时间工具使用
ChinaHoliday 类可以与 TimeHelper 类结合使用,实现更复杂的时间逻辑:
// 获取当前时间并判断是否为节假日
$currentTime = TimeHelper::now();
$isHoliday = ChinaHoliday::isHoliday($currentTime);
echo $isHoliday ? '今天是节假日' : '今天不是节假日';
流程图:节假日判断逻辑
flowchart TD
A[输入日期] --> B{是否为周末?}
B -->|是| C{是否为调休日?}
C -->|是| D[工作日]
C -->|否| E[节假日]
B -->|否| F{是否为节假日?}
F -->|是| E
F -->|否| D
通过以上案例和示例代码,开发者可以快速掌握 ChinaHoliday 类的使用方法,并将其集成到实际项目中。
与其他时间功能的结合使用
ChinaHoliday 类是 zjkal/time-helper 项目中专门用于处理中国节假日逻辑的核心类。它不仅能够独立判断某天是否为工作日或节假日,还能与项目中的其他时间功能模块(如 TimeHelper 和 TimeRange)无缝结合,提供更强大的时间处理能力。以下是一些典型的结合使用场景:
1. 结合 TimeHelper 实现动态节假日判断
TimeHelper 提供了丰富的时间格式化和转换功能,而 ChinaHoliday 则依赖于这些功能来实现动态的节假日判断。例如,ChinaHoliday::isWorkday 方法内部调用了 TimeHelper::format 和 TimeHelper::isWeekday 来完成日期格式化和工作日判断。
// 示例:判断某天是否为工作日
$date = '2025-10-01';
$isWorkday = ChinaHoliday::isWorkday($date);
echo $isWorkday ? '工作日' : '节假日';
流程图
flowchart TD
A[输入日期] --> B[TimeHelper::format]
B --> C[获取年份和月份日]
C --> D[ChinaHoliday::isWorkday]
D --> E{是否为工作日?}
E -->|是| F[返回True]
E -->|否| G[返回False]
2. 结合 TimeRange 实现节假日范围统计
虽然当前 TimeRange 类的实现较为简单,但可以通过扩展其功能,结合 ChinaHoliday 实现节假日范围的统计。例如,统计某个月份中的节假日天数:
// 示例:统计2025年10月的节假日天数
$start = '2025-10-01';
$end = '2025-10-31';
$holidays = 0;
while ($start <= $end) {
if (ChinaHoliday::isHoliday($start)) {
$holidays++;
}
$start = TimeHelper::modifyTimestamp('+1 day', $start);
}
echo "2025年10月共有 {$holidays} 个节假日";
表格:2025年节假日分布示例
| 日期 | 是否为节假日 |
|---|---|
| 2025-10-01 | 是 |
| 2025-10-02 | 是 |
| 2025-10-03 | 是 |
| 2025-10-06 | 是 |
| 2025-10-07 | 是 |
| 2025-10-08 | 是 |
3. 动态节假日与时间计算的结合
通过 TimeHelper 的时间计算功能,可以动态生成节假日提醒或倒计时。例如,计算距离下一个节假日的天数:
// 示例:计算距离下一个节假日还有多少天
$today = time();
$nextHoliday = null;
$days = 0;
while (true) {
$days++;
$date = TimeHelper::modifyTimestamp("+{$days} day", $today);
if (ChinaHoliday::isHoliday($date)) {
$nextHoliday = TimeHelper::format('Y-m-d', $date);
break;
}
}
echo "距离下一个节假日({$nextHoliday})还有 {$days} 天";
状态图
stateDiagram
[*] --> 初始化
初始化 --> 循环
循环 --> 判断节假日
判断节假日 -->|是| 输出结果
判断节假日 -->|否| 增加天数
增加天数 --> 循环
4. 节假日与工作日转换
结合 TimeHelper 的时间修改功能,可以实现工作日的动态调整。例如,跳过节假日计算某个任务的实际完成日期:
// 示例:跳过节假日计算任务完成日期
$startDate = '2025-10-01';
$workDays = 5;
$currentDate = $startDate;
$completedDays = 0;
while ($completedDays < $workDays) {
if (ChinaHoliday::isWorkday($currentDate)) {
$completedDays++;
}
$currentDate = TimeHelper::modifyTimestamp('+1 day', $currentDate);
}
echo "任务将在 {$currentDate} 完成";
代码说明
ChinaHoliday::isWorkday用于判断是否为工作日。TimeHelper::modifyTimestamp用于动态调整日期。
通过这些结合使用的方式,ChinaHoliday 类能够更灵活地服务于各种时间处理需求,提升开发效率。
ChinaHoliday 类通过精准的节假日判断、灵活的日期输入支持、高效的逻辑实现以及与其他时间功能的无缝集成,为开发者提供了一个强大且易用的工具。无论是判断特定日期是否为节假日,还是结合其他时间功能实现更复杂的逻辑,ChinaHoliday 类都能满足多样化的需求,极大提升了开发效率。
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00