首页
/ 中国节假日功能解析:zjkal/time-helper 的 ChinaHoliday 类

中国节假日功能解析:zjkal/time-helper 的 ChinaHoliday 类

2026-02-04 04:35:31作者:卓炯娓

本文详细解析了 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:判断是否为节假日。

其内部逻辑通过以下步骤实现:

  1. 提取日期的年份和月份日信息(Ymd)。
  2. 检查是否为周末或调休日。
  3. 结合节假日数据返回判断结果。
flowchart TD
    A[输入日期] --> B{是否为工作日?}
    B -->|是| C[返回 True]
    B -->|否| D[返回 False]

4. 易于维护和扩展

ChinaHoliday 类的设计注重可维护性:

  • 静态数组 $holiday$workday 按年份组织,便于更新。
  • 逻辑清晰,便于后续扩展(如支持更多年份或自定义节假日)。

5. 与 TimeHelper 的无缝集成

ChinaHoliday 类依赖于 TimeHelper 类进行日期格式化,这种设计避免了重复造轮子,同时也确保了日期处理的一致性。

通过以上设计目标,ChinaHoliday 类为开发者提供了一个强大且易用的工具,满足了中国节假日判断的多样化需求。

工作日与节假日的判断逻辑

在中国,节假日和工作日的安排往往较为复杂,尤其是调休和法定假日的存在,使得简单的周末判断无法满足需求。ChinaHoliday 类通过预定义的节假日和调休日数据,结合时间判断逻辑,提供了精准的工作日和节假日判断功能。

核心逻辑解析

ChinaHoliday 类的工作日和节假日判断逻辑基于以下两个核心条件:

  1. 是否为工作日

    • 如果日期是平常日(周一至周五),并且该日期不在预定义的节假日列表中,则判定为工作日。
    • 如果日期是周末(周六或周日),但在预定义的调休日列表中,则判定为工作日。
  2. 是否为节假日

    • 直接通过 !isWorkday() 方法判断,即非工作日即为节假日。

代码实现

以下是 isWorkdayisHoliday 方法的实现逻辑:

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. 判断特定日期是否为工作日或节假日

以下代码展示了如何使用 isWorkdayisHoliday 方法判断特定日期是否为工作日或节假日:

// 判断 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 项目中专门用于处理中国节假日逻辑的核心类。它不仅能够独立判断某天是否为工作日或节假日,还能与项目中的其他时间功能模块(如 TimeHelperTimeRange)无缝结合,提供更强大的时间处理能力。以下是一些典型的结合使用场景:

1. 结合 TimeHelper 实现动态节假日判断

TimeHelper 提供了丰富的时间格式化和转换功能,而 ChinaHoliday 则依赖于这些功能来实现动态的节假日判断。例如,ChinaHoliday::isWorkday 方法内部调用了 TimeHelper::formatTimeHelper::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 类都能满足多样化的需求,极大提升了开发效率。

登录后查看全文
热门项目推荐
相关项目推荐