PHP Calendar
Calendar functions: days in a month, Julian day conversion, Easter dates.
Key PointsThe Calendar extension covers Gregorian, Julian, Jewish and French Republican calendars.
Functions
| Function | Purpose |
|---|---|
| cal_days_in_month | 某年某月有多少天 |
| cal_info | 历法信息(月份名等) |
| cal_to_jd | 历法日期转儒略日 |
| cal_from_jd | 儒略日转历法日期 |
| easter_date | 某年复活节的时间戳 |
| easter_days | 复活节距 3 月 21 日的天数 |
| gregoriantojd | 公历转儒略日 |
| jdtogregorian | 儒略日转公历 |
| jddayofweek | 星期几 |
| jdmonthname | 月份名 |
| jdtojulian | 儒略日转儒略历 |
Month length and Easter
PHP
<?php
date_default_timezone_set("Asia/Shanghai");
echo cal_days_in_month(CAL_GREGORIAN, 2, 2024), "\n";
echo cal_days_in_month(CAL_GREGORIAN, 2, 2023), "\n";
echo cal_days_in_month(CAL_GREGORIAN, 4, 2023), "\n";
echo date("Y-m-d", easter_date(2024)), "\n";
echo easter_days(2024), "\n";Output
29
28
30
2024-03-31
10easter_days(2024) returns 10 — Easter is 10 days after 21 March, i.e. 31 March. It is timezone-independent, unlike easter_date.
easter_date() relies on Unix timestamps — unusable before 1970 or after 2037. Use easter_days() for wide ranges.Julian day
Julian Day is a continuous day count starting 4713 BC. It is the natural pivot for cross-calendar arithmetic.
PHP
<?php
$jd = gregoriantojd(11, 15, 2023);
echo $jd, "\n";
echo jdtogregorian($jd), "\n";
echo jdtojulian($jd), "\n";
echo jddayofweek($jd, 0), " ", jddayofweek($jd, 1), " ", jddayofweek($jd, 2), "\n";
echo jdmonthname($jd, 1), "\n";
// 日期差直接用减法
$jd2 = gregoriantojd(12, 25, 2023);
echo $jd2 - $jd, "\n";Output
2460264
11/15/2023
11/2/2023
3 Wednesday Wed
November
40The same Julian Day is 11/15/2023 in Gregorian and 11/2/2023 in Julian — 13 days apart. That is why historical dates must name their calendar.
| Mode | jddayofweek | jdmonthname |
|---|---|---|
| 0 | 0-6(周日为 0) | 缩写月名 |
| 1 | 英文全名 | 全称月名 |
| 2 | 英文缩写 | 儒略历缩写 |
| 3 | — | 儒略历全称 |
Calendar constants
| Constant | Calendar |
|---|---|
| CAL_GREGORIAN | 公历(现行) |
| CAL_JULIAN | 儒略历 |
| CAL_JEWISH | 犹太历 |
| CAL_FRENCH | 法国共和历 |
| CAL_NUM_CALS | 支持的历法数量 |
PHP
<?php
$jd = cal_to_jd(CAL_JEWISH, 1, 1, 5784);
echo $jd, "\n";
$d = cal_from_jd($jd, CAL_GREGORIAN);
echo $d["date"], "\n";
echo $d["monthname"], "\n";
echo cal_info(CAL_GREGORIAN)["months"][11], "\n";Output
2460292
9/16/2023
September
Novembercal_from_jd returns date, month, day, year, dow, day names and month names. Using date is more reliable than manual formatting.Practical uses
- Month-end closing ——
cal_days_in_monthinstead of hardcoding 28/30/31 - Scheduling ——
jddayofweekto detect weekends - Holiday maths —— Easter, Thanksgiving-style nth-weekday rules
- Historical dates —— pre-1582 dates need an explicit calendar
Everyday work needs only
DateTime. The Calendar extension is for non-Gregorian calendars and religious holidays. date("t") already gives days in month.函数
| 函数 | 作用 |
|---|---|
| cal_days_in_month | 某年某月有多少天 |
| cal_info | 历法信息(月份名等) |
| cal_to_jd | 历法日期转儒略日 |
| cal_from_jd | 儒略日转历法日期 |
| easter_date | 某年复活节的时间戳 |
| easter_days | 复活节距 3 月 21 日的天数 |
| gregoriantojd | 公历转儒略日 |
| jdtogregorian | 儒略日转公历 |
| jddayofweek | 星期几 |
| jdmonthname | 月份名 |
| jdtojulian | 儒略日转儒略历 |
月天数与复活节
PHP
<?php
date_default_timezone_set("Asia/Shanghai");
echo cal_days_in_month(CAL_GREGORIAN, 2, 2024), "\n";
echo cal_days_in_month(CAL_GREGORIAN, 2, 2023), "\n";
echo cal_days_in_month(CAL_GREGORIAN, 4, 2023), "\n";
echo date("Y-m-d", easter_date(2024)), "\n";
echo easter_days(2024), "\n";Output
29
28
30
2024-03-31
10easter_days(2024) 返回 10,表示复活节是 3 月 21 日之后的第 10 天,即 3 月 31 日。这个函数不依赖时区,比 easter_date 更稳。
easter_date() 内部用 Unix 时间戳,1970 年之前和 2037 年之后不可用。跨年范围的需求用 easter_days() 自己算。儒略日
儒略日(Julian Day)是一个连续的日数计数,从公元前 4713 年 1 月 1 日开始。跨历法计算时用它做中转最方便。
PHP
<?php
$jd = gregoriantojd(11, 15, 2023);
echo $jd, "\n";
echo jdtogregorian($jd), "\n";
echo jdtojulian($jd), "\n";
echo jddayofweek($jd, 0), " ", jddayofweek($jd, 1), " ", jddayofweek($jd, 2), "\n";
echo jdmonthname($jd, 1), "\n";
// 日期差直接用减法
$jd2 = gregoriantojd(12, 25, 2023);
echo $jd2 - $jd, "\n";Output
2460264
11/15/2023
11/2/2023
3 Wednesday Wed
November
40同一个儒略日在公历是 11/15/2023,在儒略历是 11/2/2023——两个历法差 13 天。这就是「历史日期」必须说明历法的原因。
| 模式 | jddayofweek | jdmonthname |
|---|---|---|
| 0 | 0-6(周日为 0) | 缩写月名 |
| 1 | 英文全名 | 全称月名 |
| 2 | 英文缩写 | 儒略历缩写 |
| 3 | — | 儒略历全称 |
历法常量
| 常量 | 历法 |
|---|---|
| CAL_GREGORIAN | 公历(现行) |
| CAL_JULIAN | 儒略历 |
| CAL_JEWISH | 犹太历 |
| CAL_FRENCH | 法国共和历 |
| CAL_NUM_CALS | 支持的历法数量 |
PHP
<?php
$jd = cal_to_jd(CAL_JEWISH, 1, 1, 5784);
echo $jd, "\n";
$d = cal_from_jd($jd, CAL_GREGORIAN);
echo $d["date"], "\n";
echo $d["monthname"], "\n";
echo cal_info(CAL_GREGORIAN)["months"][11], "\n";Output
2460292
9/16/2023
September
Novembercal_from_jd 返回的数组包含 date、month、day、year、dow、abbrevdayname、monthname、abbrevmonthname。用 date 拼字符串比自己格式化可靠。实际用途
- 财务月结 —— 用
cal_days_in_month算月末日期,避免手写 28/30/31 - 排班 / 排课 —— 结合
jddayofweek判断周末 - 节假日计算 —— 复活节、感恩节这类「第 N 个星期几」
- 历史日期 —— 涉及 1582 年之前的日期要明确历法
日常业务**用
DateTime 就够了**,Calendar 扩展主要处理「非公历」和「宗教节日」。别为了算个 2 月天数就引入它——date("t") 也能做到。