為什么說這個 Calendar 擴展很好玩呢?因為你基本用不到它!這個擴展是一套關于日期歷法的擴展,但是對于我們來說,它沒有農歷的相關操作,所以對于我們中國人來說這個擴展并沒有什么實際的作用,不過這并不妨礙我們去了解學習它,
日期歷法型別
對于正常情況下的日期操作來說,PHP 默認使用的是 UTC 時間,也就是國際標準時間,對于我們國家來說,需要在標準 UTC 的時間上加 8 來表示北京時間東八區,當然,也可以直接修改 php.ini 或者資料庫中的時區相關引數來定義好日期時區,
標準時區對應的其實就是格里高利時間歷法 Gregorian ,也就是我們現在最常用的公歷、陽歷日期,Calendar 擴展中除了這個標準的公歷歷法之外,還支持 猶太歷法 Jewish 、 法歷 French 以及另一個非常出名的 儒略歷 Julian ,我們的 Gregorian 歷法就是從 Julian 歷中演化而來的,它們的差距并不大,但 猶太歷 和 法歷 的差距就比較大了,一會在下面的代碼中我們將看到各種歷法之間的差別,
關于這些歷法的具體內容大家可以自行查詢一下相關的資料,也能夠學習到一些有趣的歷史知識,比如為什么廢棄了 儒略歷 而將公歷定為了 格里歷 ,還有 法歷 為什么只有短短的那些年,猶太歷 為什么年份記得這么大了,法歷 和 猶太歷 月份名字的來源等,都是很有趣的故事,
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] => Adar I
// [7] => Adar II
// [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] => Adar I
// [7] => Adar II
// [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時間戳為Julian Day計數
$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計數 ,
echo cal_to_jd(CAL_JEWISH, 1, 5, 5781), PHP_EOL; // 2459116
echo cal_to_jd(CAL_GREGORIAN,9, 23, 2020), PHP_EOL; // 2459116
可以看到上面 猶太歷 回傳的 jd計數 和我們公歷回傳的 jd計數 是一致的,
當然,我們也可以將 jd計數 的日期轉換成 unix 時間,
echo date("Y-m-d", jdtounix($today)), PHP_EOL;
// 2020-09-23
除了 cal_from_jd() 和 cal_to_jd() 之外,Calendar 擴展還為我們提供了一些快捷的函式進行日期的轉換,只不過它們是直接回傳的字串型別的日期資訊,不是像 cal_from_jd() 函式一樣回傳日期的詳細資訊,
// 轉變一個Gregorian歷法日期到Julian Day計數
$jd = GregorianToJD(9, 23, 2020);
// 轉變一個Julian Day計數為Gregorian歷法日期
echo jdtogregorian($jd), PHP_EOL; // 9/23/2020
// 轉變一個Julian Day計數為Julian歷法日期
echo jdtojulian($jd), PHP_EOL; // 9/10/2020
// 轉變一個Julian Day計數為猶太歷法日期
echo jdtojewish($jd), PHP_EOL; // 1/5/5781
// 轉變一個Julian Day計數為unix時間戳
echo jdtounix($jd), PHP_EOL; // 1600819200
$jd = GregorianToJD(9, 23, 1799);
// 轉變一個Julian Day計數為French歷法日期
echo jdtofrench($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 擴展中就有函式可以直接獲得指定年份的復活節日期,關于復活節的計算方式其實還是比較復雜的,手工推算是比較麻煩的,而程式計算就非常方便了,
// 指定年份的復活節時間戳
echo date("M-d-Y", easter_date(2019)), PHP_EOL; // Apr-21-2019
echo date("M-d-Y", easter_date(2020)), PHP_EOL; // Apr-12-2020
echo date("M-d-Y", easter_date(2021)), PHP_EOL; // Apr-04-2021
// 3月21日到復活節之間的天數
echo easter_days(2019), PHP_EOL; // 31
echo easter_days(2020), PHP_EOL; // 22
echo easter_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
===============
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/288673.html
標籤:其他
