也談農曆置閏

2022-03-24 00:08:58 字數 1016 閱讀 4853

在看王曉華所著《演算法的樂趣》(王曉華著. 演算法的樂趣[m]. 北京:人民郵電出版社, 2015.04.)第11章中給出的農曆程式源**時,發現在農曆置閏方面似乎有點問題,值得商榷。

書中給出的農曆閏月設定規則與《gb/t 33661-2017 農曆的編算和頒行》相一致,但長篇大論的比國標長多了,所以直接引用國標原文吧:

4 農曆的編排規則

4.1 以北京時間為標準時間。

4.2 朔日為農曆月的第乙個農曆日。

4.3 包含節氣冬至在內的農曆月為農曆十一月。

4.4 若從某個農曆十一月開始到下乙個農曆十一月(不含)之間有13個農曆月,則需要置閏。置閏規則為:取其中最先出現的乙個不包含中氣的農曆月為農曆閏月。

4.5 農曆十一月之後第2個(不計閏月)農曆月為農曆年的起始月。

書中判斷是否需要置閏的**是cchinesecalendar::calcleapchnmonth(),沒有該書或沒有該書源**的可以看這裡,有相同的文字說明和源**:

calcleapchnmonth函式**初看沒有問題,與國標中4.4相一致,但其實存在乙個邏輯漏洞: **中的m_newmoonjd陣列是從前一年的十一月(冬至月)開始的,因此**

if(int(m_newmoonjd[13] + 0.5) <= int(m_solartermsjd[24] + 0.5)) //第13月的月末沒有超過冬至,說明今年需要閏乙個月

考慮了本年前11個月是否需要置閏,但漏掉了另外乙個考慮選項:本年的第12個月(m_newmoonjd[14])是否需要置閏?

要判斷本年第12個月是否需要置閏(閏冬月),就需要從本年冬至月計算到下年冬至月,發現有13個月時再看本年第12個月是否無中氣。簡單一點說,其實就是在用書中的**計算發現本年無閏月時,還要用相同的**再算一遍第二年的閏月看是不是本年的第十二個月。第二遍計算時m_newmoonjd陣列中儲存的是從本年冬至到下年冬至之間的朔時刻。而在用現有的**計算發現本年需要置閏時,也要檢查一下去年的冬月是否已經閏過,如果閏過就別再閏了。

如果不做這樣的修正,在碰到2023年這樣需要閏冬月的年份就會出現錯誤。

也談武媚娘

前段時間電視熱播 武媚娘 老婆天天晚上看。我不大喜歡看各種誇張和粉飾的歷史劇,但是對歷史還是喜歡一些,所以就利用閒餘的時間搜尋一下,看看唐朝的那些事。正好把自己的搜尋和感慨整理記錄下。唐朝是乙個中國發展的乙個鼎盛時期,即便如此,也是乙個多事的朝代。李世民宣武門弒兄,自己逼迫父親成為了太上皇,兒子李志...

也談介面程式設計

剛剛和大峽討論乙個問題,介面程式設計,這個話題也許大家比我理解多了,我提出乙個自己的觀點 在個人程式中空介面很少,至少我見的很少!大峽 不對,空介面很多,介面只不過是乙個標識,然後我們做了乙個很有意思的程式 空介面 package springroad.demo.taginte ce public ...

也談大數階乘

最近公司裡面的專案一直用c 來進行,基礎太薄弱,於是自己完成了公司的任務後,加緊練習。本來那天是想寫乙個遞迴階乘演算法的,發現有不少問題啊 第一 遞迴有乙個弊端,就是棧空間不夠的問題 第二 遇到大數的時候,在cpp中沒有辦法找到合適的資料型別來進行計算,用long,double都是不可能夠的。因為我...