为什么说这个 Calendar 扩展很好玩呢?由于你基本用不到它!
这个扩展是一套关于日期历法的扩展,但是对付我们来说,它没有农历的干系操作,以是对付我们中国人来说这个扩展并没有什么实际的浸染。
不过这并不妨碍我们去理解学习它。

日期历法类型

对付正常情形下的日期操作来说,PHP 默认利用的是 UTC 韶光,也便是国际标准韶光,对付我们国家来说,须要在标准 UTC 的韶光上加 8 来表示北京韶光东八区。
当然,也可以直接修正 php.ini 或者数据库中的时区干系参数来定义好日期时区。

标准时区对应的实在便是格里高利韶光历法 Gregorian 。
也便是我们现在最常用的公历、阳历日期。
Calendar 扩展中除了这个标准的公历历法之外,还支持 犹太历法 Jewish 、 法历 French 以及另一个非常出名的 儒略历 Julian 。
我们的 Gregorian 历法便是从 Julian 历中蜕变而来的,它们的差距并不大,但 犹太历 和 法历 的差距就比较大了,一会不才面的代码中我们将看到各种历法之间的差别。

好玩的phpPHP中异常好玩的Calendar扩大进修 JavaScript

关于这些历法的详细内容大家可以自行查询一下干系的资料,也能够学习到一些有趣的历史知识,比如为什么废弃了 儒略历 而将公历定为了 格里历 。
还有 法历 为什么只有短短的那些年,犹太历 为什么年份记得这么大了。
法历 和 犹太历 月份名字的来源等,都是很有趣的故事。

Calendar 扩展安装及历法信息查看

Calendar 扩展已经集成在 PHP 安装包中了,不须要特殊的单独去安装。
如果你无法利用 Calendar 干系的函数,可以重新编译 PHP 并加上 --enable-calendar 参数即可。

接下来我们看下指定历法的详细信息,这里我们指定的是 犹太历 。

$info=cal_info(2);print_r($info);//Array//(//[months]=>Array//(//[1]=>Tishri//[2]=>Heshvan//[3]=>Kislev//[4]=>Tevet//[5]=>Shevat//[6]=>AdarI//[7]=>AdarII//[8]=>Nisan//[9]=>Iyyar//[10]=>Sivan//[11]=>Tammuz//[12]=>Av//[13]=>Elul//)//[abbrevmonths]=>Array//(//[1]=>Tishri//[2]=>Heshvan//[3]=>Kislev//[4]=>Tevet//[5]=>Shevat//[6]=>AdarI//[7]=>AdarII//[8]=>Nisan//[9]=>Iyyar//[10]=>Sivan//[11]=>Tammuz//[12]=>Av//[13]=>Elul//)//[maxdaysinmonth]=>30//[calname]=>Jewish//[calsymbol]=>CAL_JEWISH//)

cal_info() 函数吸收的参数是一个常量,分别是 CAL_GREGORIAN ,CAL_JULIAN ,CAL_JEWISH ,CAL_FRENCH ,它们对应的数字便是 0,1,2,3 。
在这段代码中,我们返回的便是 CAL_JEWISH 的信息。
可以看出,犹太历 中的月份名称与公历中的英文名称都不一样,比如这里有 尼撒月 Nisan 、提市黎月 Tishri 。
详细的内容就不穷究了,毕竟我们在日常生活中是完备打仗不到这种历法的。

大家可以自己试试其它历法返回的信息内容,公历和儒略历是一样的,法历中的月份名字就又不一样了,而且这些名字还都很故意思。

日期历法转换

首先,要进行历法转换的话,我们要将指定的日期转换成 Julian Days 计数。
这个 jd 计数可以看作是 Calendar 扩展的一个中间变量,用于各种历法之间的换算。

//转变Unix韶光戳为JulianDay计数$today=unixtojd(mktime(0,0,0,9,23,2020));echo$today,PHP_EOL;//2459116

利用 unixtojd() 函数就可以将一个 unix 韶光戳转换成 jd 计数。
接下来,我们看看 2020 年 9 月 23 号对应的 犹太历 是哪一天。

//获取当前犹太历韶光print_r(cal_from_jd($today,CAL_JEWISH));//Array//(//[date]=>1/5/5781//[month]=>1//[day]=>5//[year]=>5781//[dow]=>3//[abbrevdayname]=>Wed//[dayname]=>Wednesday//[abbrevmonth]=>Tishri//[monthname]=>Tishri//)

返回的信息中已经很明确了吧,我们这一天是 犹太历 的 5781 年 1 月 5 号 星期三 。
当前的月份是 Tishri 提市黎月 ,对应着公历年的第一个月,犹太历中教会年的第七个月,代表着秋日的到来。

cal_from_jd() 函数的浸染便是根据 jd计数 返回指定历法的详细信息。
而其余一个 cal_to_jd() 函数则是从一个支持的历法数据转换为 jd计数 。

echocal_to_jd(CAL_JEWISH,1,5,5781),PHP_EOL;//2459116echocal_to_jd(CAL_GREGORIAN,9,23,2020),PHP_EOL;//2459116

可以看到上面 犹太历 返回的 jd计数 和我们公历返回的 jd计数 是同等的。

当然,我们也可以将 jd计数 的日期转换成 unix 韶光。

echodate("Y-m-d",jdtounix($today)),PHP_EOL;//2020-09-23

除了 cal_from_jd() 和 cal_to_jd() 之外,Calendar 扩展还为我们供应了一些快捷的函数进行日期的转换,只不过它们是直接返回的字符串类型的日期信息,不是像 cal_from_jd() 函数一样返回日期的详细信息。

//转变一个Gregorian历法日期到JulianDay计数$jd=GregorianToJD(9,23,2020);//转变一个JulianDay计数为Gregorian历法日期echojdtogregorian($jd),PHP_EOL;//9/23/2020//转变一个JulianDay计数为Julian历法日期echojdtojulian($jd),PHP_EOL;//9/10/2020//转变一个JulianDay计数为犹太历法日期echojdtojewish($jd),PHP_EOL;//1/5/5781//转变一个JulianDay计数为unix韶光戳echojdtounix($jd),PHP_EOL;//1600819200$jd=GregorianToJD(9,23,1799);//转变一个JulianDay计数为French历法日期echojdtofrench($jd),PHP_EOL;//1/1/8

GregorianToJD() 方法便是快捷地转换一个公历日期为 jd计数 。
而 jdtoxxxxx 为些函数便是快速地返回 jd计数 对应的日期历法的字符串信息。

大家可以把稳下,法历 日期只能是公历 1792年9月22日到1806年9月22日 这段日期以内的日期,也便是 法兰西第一共和国 成立后推出的 法历 ,并在 1806年 结束利用,由于 1804年 拿破仑 成立了 法兰西第一帝国 。
帝国破除了 法历(共和历)并全面实行 公历 。

某个月份的天数

上面的历史知识学习的怎么样?接下来还是回归到 Calendar 扩展中的学习中来。

$num=cal_days_in_month(CAL_GREGORIAN,2,2020);echo$num,PHP_EOL;//29

cal_days_in_month() 函数是返回指定历法月份的天数,比如我们看看 2020 年的 2月 是不是 闰月 就可以用这个函数来实现。

复活节彩蛋

复活节是西方非常主要的一个节日,以是在 Calendar 扩展中就有函数可以直接得到指定年份的复活节日期。
关于复活节的打算办法实在还是比较繁芜的,手工推算是比较麻烦的,而程序打算就非常方便了。

//指定年份的复活节韶光戳echodate("M-d-Y",easter_date(2019)),PHP_EOL;//Apr-21-2019echodate("M-d-Y",easter_date(2020)),PHP_EOL;//Apr-12-2020echodate("M-d-Y",easter_date(2021)),PHP_EOL;//Apr-04-2021//3月21日到复活节之间的天数echoeaster_days(2019),PHP_EOL;//31echoeaster_days(2020),PHP_EOL;//22echoeaster_days(2021),PHP_EOL;//14

easter_date() 函数便是返回指定年份的复活节日期。
而 easter_days() 函数则是返回从当年公历的 3月21日 到复活节之间的天数。

复活节是每年春分月圆后的第一个星期日,而春分一样平常是在3月21日,这就简化为只要打算满月的日期和紧挨的星期日的日期就可以得到每年复活节的详细日期了。
这种函数在西方天下的软件开拓中会非常常用,实在就像我们须要获取每年春节的详细公历日期一样。

总结

是不是很故意思的一套扩展函数。
不过对付我们紧张面向海内开拓的开拓者来说用途确实不大,但笔者在学习这个扩展的时候其余收成了不少历史方面的知识,也算是开了眼界,也不失落为一大收成,大家也自己试着玩玩并且查查干系的历史知识吧,说不定你的收成会更多!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/10.PHP中非常好玩的Calendar扩展学习.php

参考文档:

https://www.php.net/manual/zh/book.calendar.php