在Python中计算农历/阴历节日
这里有对日历感兴趣的朋友吗?我一直在寻找关于如何计算当前年份在公历中不规律出现的假期的信息。通常,这种情况发生是因为假期是基于较旧的农历。
我在网上查了很多资料,虽然有了一些进展,但还是没能完成。如果有人能提供一些现代编程语言的示例代码,描述他们的计算方法,我会非常感激。我更倾向于使用Python或者C系列语言。
到目前为止我的进展:
完成的部分:
- 复活节:可以通过python-dateutil找到。
- 光明节和其他希伯来历的假期可以通过holiday.py从python date_util*s*中找到。
接近完成的部分:
- 斋月:date_utils中有一个伊斯兰日历的功能,我试过,结果大部分是正确的,但并不完全准确。(它想把所有日期转换为儒略日,我不太明白为什么)。
import calendar_util as cu # from date utils; no jokes from .br
#
# year = int(sys.argv1) or datetime.now().year
tj = cu.gregorian_to_jd(year, 1, 1) # this year in julian
ti = cu.jd_to_islamic(tj) # this year in islamic cal
rj = cu.islamic_to_jd(ti[0], 9, 1) # first day of ramadan in julian
#
print cu.jd_to_gregorian(rj) # first day of ramadan in greg
# output: (2011, 8, 1) # correct
在2014年和2016年,我得到的结果相差一天,这一点可以通过这个网站确认,虽然它提到的“北美观测”对我来说有点模糊。我希望能得到一些提高准确性的建议,比如如果1月1日碰上某个年度截止日期。伊斯兰年的长度较短,因此每年到来的时间会更早。
没有找到的部分:
- 春节:我只找到过这个讨论,但答案并没有揭示出来。
值得一提的是,我在网上找到一个链接,指向这本书,售价30美元,但我不想为几行代码花那么多钱。如果讨论中提到的例程都在Emacs日历中,但我从来没有安装过Emacs,所以如果这是唯一可用的代码,希望有人能帮我找出来并简化一下,以便我能得到当前年份的斋月和春节日期。
不确定这是否有用,但太阳和月亮的事件可以通过pyephem获取,我已经在使用这个。也许它也能派上用场。
2 个回答
我已经用现有的库写了这两个代码。
这是关于斋月的代码:
from convertdate import islamic
def ramadan(year):
islamic_year = islamic.from_gregorian(year, 1, 1)[0]
result = islamic.to_gregorian(islamic_year, 9, 1)
if result[0] < year:
result = islamic.to_gregorian(islamic_year+1, 9, 1)
elif result[0] > year:
result = islamic.to_gregorian(islamic_year-1, 9, 1)
return date(*result)
这是关于春节的代码:
from lunardate import LunarDate
_yot = ('Rat', 'Ox', 'Tiger', 'Rabbit', 'Dragon', 'Snake', 'Horse', 'Goat', 'Monkey', 'Rooster', 'Dog', 'Pig')
def year_of_the(year):
yr = (year - 2020) % len(_yot)
return _yot[yr]
def chinese_new_year(year):
"""Returns a tuple of the (date, year_of_the: str)"""
return (LunarDate(year, 1, 1).toSolarDate(), year_of_the(year))
我还提交了一个功能增强请求,希望convertdate能把这两个节日加进去:https://github.com/fitnr/convertdate/issues/24
虽然我没有代码可以给你,但我可以提供一些信息,可能会帮助你取得进展。
首先,儒略日是计算月亮和阴阳历日期的基础,因为它以国际单位制(SI)秒为单位进行计时,这种计时方式是基于地球的形状。通过公式可以很容易地计算出这些事件之间的SI秒数。你可以在这里了解更多:http://en.wikipedia.org/wiki/Julian_day
阴阳历的节日和希伯来历的规划,主要依赖于月亮的相位和太阳的星期几之间的关系。在希伯来历和伊斯兰历中,一天是从日落开始的。所以如果月亮在日落时达到100%的相位,这会影响节日的时间以及未来日历的安排。但是,日落的具体时间是什么时候呢?这不仅取决于经度,还与观察地点的纬度有关。因此,你必须从地球上的特定位置来规划阴阳历和节日。更多信息可以查看这里:http://en.wikipedia.org/wiki/Jewish_calendar#Principles
这些因素导致了简化的教会系统的使用,这些系统在世界上广泛应用,用于计算复活节的日期,而不是直接进行天文观察。你可以了解更多:http://en.wikipedia.org/wiki/Computus
传统的伊斯兰历要求根据天文观察(包括日落)来定义,因此如果你想预测节日的日期和时间间隔,就需要与地球上的特定位置相结合。这可能就是你提到的“北美观察”和未来节日日期错误的原因;如果在北美观察月相与太阳日,而不是在麦加,日历的规划会有很大不同。
在预测任何天文现象(因此也包括月亮或阴阳历事件)时,有一个不可避免且无法预测的因素,就是地球自转随时间的变化。虽然有一个简单的公式可以估算这种变化,但实际的测量是通过来自非常遥远的天体的信号来完成的。你可以在这里了解更多:http://en.wikipedia.org/wiki/Leap_second。由于这种不确定性,以及某些日历对月相和太阳历的敏感性,这些日历总会有一个遥远的未来界限,超过这个界限,日期的顺序就无法确定了。
PyEphem看起来是一个非常酷的包,我也会自己去看看。如果它的内置逻辑不能满足你的需求,你可能需要花费相当多的时间来研究如何预测未来的天文事件。这里有个小提示:http://en.wikipedia.org/wiki/Precession_of_the_equinoxes#Values
再次强调,我没有具体的代码给你,但我希望这些信息对你有帮助,而不是重复你已经知道的内容。