文章目录
格里历(公历)生成算法
格里历的历法规则
分为平常年和闰年:
1.如果年份是4的倍数,且不是100的倍数,则是闰年;
2.如果年份是400的倍数,则是闰年;
3.不满足1.2条件的就是平常年。
def is_leap_year(year):
if (year % 4 == 0 and year % 100 != 0) or (year % 400) == 0:
return '%d年是闰年' % year
else:
return '%d年不是闰年' % year
for year in range(1995, 2020):
print(is_leap_year(year))
1995年不是闰年
1996年是闰年
1997年不是闰年
1998年不是闰年
1999年不是闰年
2000年是闰年
2001年不是闰年
2002年不是闰年
2003年不是闰年
2004年是闰年
2005年不是闰年
2006年不是闰年
2007年不是闰年
2008年是闰年
2009年不是闰年
2010年不是闰年
2011年不是闰年
2012年是闰年
2013年不是闰年
2014年不是闰年
2015年不是闰年
2016年是闰年
2017年不是闰年
2018年不是闰年
2019年不是闰年
今天星期几
直接根据日期的差值
两个日期之间相隔的天数分为三个部分:
前一个日期所在年份还剩下的天数+两个日期之间相隔的整数年包含的天数+后一个日期所在的年过去的天数
对7取余数
def is_leap_year(year):
"""是否是闰年"""
if (year % 4 == 0 and year % 100 != 0) or (year % 400) == 0:
return 1
else:
return 0
def pass_day(day):
"""一年过去了多少天"""
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
passday = day[2]
if is_leap_year(day[0]):
days[1] = 29
i = 0
while i < day[1] - 1:
passday += days[i]
i += 1
return passday
def what_day(day1, day2):
"""今天星期几"""
day1 = [int(i) for i in day1.split('-')]
day2 = [int(i) for i in day2.split('-')]
sumday = 0
# 中间相隔的年数
middle_year = day1[0] + 1
while middle_year < day2[0]:
if is_leap_year(middle_year):
sumday += 366
else:
sumday += 365
middle_year += 1
# 前一个日期还剩下的天数
if is_leap_year(day1[0]):
sumday += 366 - pass_day(day1)
else:
sumday += 365 - pass_day(day1)
# 后一个日期过去的天数
sumday += pass_day(day2)
return (sumday % 7)
print(what_day('1977-3-27', '2005-5-31'))
2
利用儒略历计算日期的差值
儒略日(Julian Day,JD):从公元前4713年1月1日UTC12:00开始所经过的天数。这天对应的是星期一。
J
D
=
⌊
153
m
+
2
5
⌋
+
365
y
+
⌊
y
4
⌋
−
⌊
y
100
⌋
+
⌊
y
400
⌋
+
d
a
y
−
32045
JD = \lfloor \frac{153m+2}{5} \rfloor +365y + \lfloor \frac{y}{4} \rfloor - \lfloor \frac{y}{100} \rfloor + \lfloor \frac{y}{400} \rfloor + day - 32045
JD=⌊5153m+2⌋+365y+⌊4y⌋−⌊100y⌋+⌊400y⌋+day−32045
其中:
a
=
⌊
14
−
m
o
n
t
h
12
⌋
a = \lfloor \frac{14-month}{12} \rfloor
a=⌊1214−month⌋
y
=
y
e
a
r
+
4800
−
a
y = year + 4800 - a
y=year+4800−a
m
=
m
o
n
t
h
+
12
a
−
3
m = month + 12a -3
m=month+12a−3
其中
y
e
a
r
,
m
o
n
t
h
,
d
a
y
year,month,day
year,month,day分别代表年份,月份和日期。
def JD(day):
"""今天星期几"""
day = [int(i) for i in day.split('-')]
year = day[0]
month = day[1]
day = day[2]
a = int((14 - month)/12)
y = year + 4800 - a
m = month + 12*a -3
return int((153*m+2)/5) + 365*y + int(y/4) - int(y/100) + int(y/400) + day - 32045
day1 = JD('1977-3-27')
day2 = JD('2005-5-31')
difference = day2 - day1
print(difference%7)
2
利用蔡勒公式计算星期数
公元前1年的12月31日是星期日,作为标准日期,来对日期进行推导:
w
=
(
(
y
e
a
r
−
1
)
×
365
+
⌊
y
4
⌋
−
⌊
y
100
⌋
+
⌊
y
400
⌋
+
D
)
%
7
w=((year-1)×365 + \lfloor \frac{y}{4} \rfloor - \lfloor \frac{y}{100} \rfloor + \lfloor \frac{y}{400} \rfloor + D)\%7
w=((year−1)×365+⌊4y⌋−⌊100y⌋+⌊400y⌋+D)%7
其中:
y
e
a
r
year
year为年份,
D
D
D为已经过去的天数。
def is_leap_year(year):
"""是否是闰年"""
if (year % 4 == 0 and year % 100 != 0) or (year % 400) == 0:
return 1
else:
return 0
def pass_day(day):
"""一年过去了多少天"""
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
passday = day[2]
if is_leap_year(day[0]):
days[1] = 29
i = 0
while i < day[1] - 1:
passday += days[i]
i += 1
return passday
def what_day(day):
day = [int(i) for i in day.split('-')]
d = day[0] - 1
return (d*365+int(d/4)-int(d/100)+int(d/400)+pass_day(day))%7
print(what_day("2005-5-31"))
2
蔡勒公式:
w
=
(
y
+
⌊
y
4
⌋
+
⌊
c
4
⌋
−
2
c
+
⌊
13
(
m
+
1
)
5
⌋
+
d
−
1
)
%
7
w = (y+\lfloor \frac{y}{4} \rfloor + \lfloor \frac{c}{4} \rfloor - 2c + \lfloor \frac{13(m+1)}{5} \rfloor + d - 1)\%7
w=(y+⌊4y⌋+⌊4c⌋−2c+⌊513(m+1)⌋+d−1)%7
其中:
c
c
c:世纪数减一的值
m
m
m:月数,大于等于3,小于等于14,一月和二月看做上一年的13月和14月
y
y
y:年份,取后两位
d
d
d:某月内的日数
def zeller(day):
day = [int(i) for i in day.split('-')]
# c
c = day[0] // 100
# m
if day[1] < 3:
m = day[1] + 12
else:
m = day[1]
# y
y = day[0] % 100
# d
d = day[2]
return (y + int(y/4) + int(c/4) - 2*c + int(13*(m+1)/5) + d - 1) % 7
print(zeller('2005-5-31'))
2
生成日历的算法
def is_leap_year(year):
"""是否是闰年"""
if (year % 4 == 0 and year % 100 != 0) or (year % 400) == 0:
return 1
else:
return 0
def zeller(year, month, day):
# c
c = year // 100
# m
if month < 3:
m = month + 12
else:
m = month
# y
y = year % 100
# d
d = day
return (y + int(y/4) + int(c/4) - 2*c + int(13*(m+1)/5) + d - 1) % 7
# 月份的天数
def month_day(year, month):
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if is_leap_year(year):
days[1] = 29
day = days[month-1]
return day
def print_month_calendar(year, month):
days = month_day(year, month)
week = zeller(year, month, 1)
print('======================%d年%d月======================' % (year, month))
print("日\t一\t二\t三\t四\t五\t六")
i = 1
while i <= days:
print(i,'\t', end='')
if week == 6:
print('\n')
i += 1
week = (week+1) % 7
print('\n')
if __name__ == "__main__":
for i in range(1, 13):
print_month_calendar(2019, i)
======================2019年1月======================
日 一 二 三 四 五 六
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
======================2019年2月======================
日 一 二 三 四 五 六
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
======================2019年3月======================
日 一 二 三 四 五 六
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
======================2019年4月======================
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
======================2019年5月======================
日 一 二 三 四 五 六
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
======================2019年6月======================
日 一 二 三 四 五 六
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
======================2019年7月======================
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
======================2019年8月======================
日 一 二 三 四 五 六
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
======================2019年9月======================
日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
======================2019年10月======================
日 一 二 三 四 五 六
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
======================2019年11月======================
日 一 二 三 四 五 六
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
======================2019年12月======================
日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
二十四节气的天文学计算
二十四节气的起源
二十四节气起源于中国黄河流域。远在春秋时代,g古人就开始使用仲春、仲夏、仲秋和仲冬四个节气指导农耕种植。后来经过不断地改进与完善,到秦汉年间,二十四节气已经基本确立。
公元前104年(汉武帝太初元年),汉武帝颁布由邓平等人制定的《太初历》正式把二十四节气订于历法,明确了二十四节气的天文位置。
二十四节气天文位置的定义,就是从太阳黄经零度开始,沿黄经每运行15度所经历的时日称为一个节气。太阳一个回归年运行360度,共经历二十四个节气,每个公历月对应两个节气。
其中,每月第一个节气为“节令”,即立春、惊蛰、清明、立夏、芒种、小暑、立秋、白露、寒露、立冬、大雪和小寒十二个节令;
每月的第二个节气为“中气”,即雨水、春分、谷雨、小满、夏至、大暑、处暑、秋分、霜降、小雪、冬至和大寒十二个中气。
“节令”和“中气”交替出现,各历时15天,人们习惯上把“节令”和“中气”统称为“节气”。
二十四节气的天文学定义
补充补充天文学知识