首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 精確計算復活節日期:Gauss 演算法完整實作與年份驗證

     編輯:PHP 綜合知識

復活節日期規則

復活節定義為「春分後第一個滿月之後的第一個星期日」。Gauss 演算法(1800 年發表)可精確計算西元 1583 年(格里曆啟用)至 9999 年的復活節日期。

完整可用的 PHP 實作

<?php
/**
 * 計算指定年份的復活節日期(西方教會/格里曆)
 * 
 * @param int $year 年份(1583-9999)
 * @return DateTime|null 復活節日期,失敗回傳 null
 */
function calculateEasterSunday(int $year): ?DateTime
{
    if ($year < 1583 || $year > 9999) {
        return null;
    }

    // Gauss 演算法核心步驟
    $a = $year % 19;           // 黃金數
    $b = (int)($year / 100);   // 世紀
    $c = $year % 100;          // 年份在世紀內的位置
    $d = (int)($b / 4);        // 世紀閏年修正
    $e = $b % 4;
    $f = (int)(($b + 8) / 25); // 朔望月修正
    $g = (int)(($b - $f + 1) / 3);
    $h = (19 * $a + $b - $d - $g + 15) % 30; // 朔望月日期
    $i = (int)($c / 4);
    $k = $c % 4;
    $l = (32 + 2 * $e + 2 * $i - $h - $k) % 7; // 星期幾修正
    $m = (int)(($a + 11 * $h + 22 * $l) / 451); // 例外修正
    
    $month = (int)(($h + $l - 7 * $m + 114) / 31); // 3=三月, 4=四月
    $day = (($h + $l - 7 * $m + 114) % 31) + 1;

    return DateTime::createFromFormat('Y-m-d', sprintf('%04d-%02d-%02d', $year, $month, $day));
}

// 批次驗證 2020-2030 年
for ($y = 2020; $y <= 2030; $y++) {
    $date = calculateEasterSunday($y);
    echo $date ? $date->format('Y-m-d (D)') : "Year $y error", "\n";
}
/*
2020-04-12 (Sun)
2021-04-04 (Sun)
2022-04-17 (Sun)
2023-04-09 (Sun)
2024-03-31 (Sun)
2025-04-20 (Sun)
2026-04-05 (Sun)
2027-03-28 (Sun)
2028-04-16 (Sun)
2029-04-01 (Sun)
2030-04-21 (Sun)
*/

延伸:計算相關節期

function getLiturgicalDates(int $year): array
{
    $easter = calculateEasterSunday($year);
    if (!$easter) return [];

    $dates = ['easter' => clone $easter];
    $intervals = [
        'ash_wednesday' => '-46 days',      // 聖灰星期三
        'palm_sunday' => '-7 days',         // 棕枝主日
        'maundy_thursday' => '-3 days',     // 濯足星期四
        'good_friday' => '-2 days',         // 受難節
        'holy_saturday' => '-1 day',        // 聖週六
        'ascension' => '+39 days',          // 升天節
        'pentecost' => '+49 days',          // 五旬節
        'corpus_christi' => '+60 days',     // 基督聖體節
    ];

    foreach ($intervals as $name => $interval) {
        $dt = clone $easter;
        $dt->modify($interval);
        $dates[$name] = $dt;
    }
    return $dates;
}

效能與快取建議

演算法純整數運算,極快(微秒級)。若頻繁查詢同年份,建議以陣列或 Redis 快取 year => date 對應。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved