-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhenning_c.py
130 lines (108 loc) · 4.71 KB
/
henning_c.py
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/python
# Convert between Henning's tropical Tibetan calendar and Julian Days, with Chinese leap month rule
from math import floor, ceil
from fractions import Fraction
from months import NUM_TIBETAN as MONTHS, TIBETAN_NUM as MONTHNO
from solun import tropical_year as trop_year, lunar_month as syn_month, newmoon, trans, solar_term as st, phase, phasetime
tz = Fraction(6,24) # Xinjiang time; Tibet officially uses Beijing time, but Xinjiang time gives more correct results
solar_epoch = 2096243 # approximate time of the northward equinox in the era year
def dayof(jday):
'''Determine whether an astronomical event is associated with today or tomorrow.'''
jday = Fraction(jday)
if (jday % 1 < Fraction(5,24)):
ans = floor(jday)
else:
ans = ceil(jday)
return ans
def moonof(jday):
'''Compute the new moon associated with an astronomical event'''
jday = Fraction(jday)
crescent = newmoon(jday, tz)
while( dayof(newmoon(crescent, tz)) > dayof(jday)):
crescent -= syn_month
while( dayof(newmoon((crescent + syn_month), tz)) <= dayof(jday)):
crescent += syn_month
return crescent
def fromjd(jday):
'''Convert a Julian Day into a date in the Indian-style tropical Tibetan calendar'''
jday = Fraction(jday)
# begin with the month
c = moonof(jday) # new moon that commences the month we're in
# compute for the year
year = (jday - solar_epoch) // trop_year
equinox = trans( (solar_epoch + (year * trop_year)), 0, tz)
while( moonof(trans((equinox + trop_year), 0, tz)) <= jday):
year += 1
equinox += trop_year
while( moonof(trans(equinox, 0, tz)) > jday):
year -= 1
equinox -= trop_year
# compute the month
crescent = newmoon(moonof(trans(equinox, 0, tz)), tz)
if( round( (newmoon(moonof(trans((equinox + trop_year), 0, tz)), tz) - newmoon(crescent, tz)) / syn_month) == 12):
# normal year
month = MONTHS[round( (moonof(jday) - crescent) / syn_month)]
else:
# leap year
m = 0 # number of the month
z = 0 # ecliptic longitude of the next solar term, starting with the northward equinox
l = False # have we passed the leap month?
zhongqi = equinox # next zhongqi the lunation has to straddle to count, starting with the northward equinox
while(moonof(crescent + syn_month) <= jday):
if(l):
# we are passed the leap month
m += 1
elif( moonof(crescent + syn_month) < dayof(trans(zhongqi, z, tz))):
# this is the leap month
l = True
else:
m += 1
z += 30
zhongqi += st
crescent += syn_month
month = MONTHS[m]
if( (not l) and ( moonof(crescent + syn_month) < dayof(trans(zhongqi, z, tz)))):
# it's the leap month
month = "Leap " + month
# finally, compute the tithi
tithi = int(phase( (jday + Fraction(5,24)), tz) // 12) + 1 # add 1 because humans don't count from 0
return(tithi, month, year)
def tojd(tithi, month, year):
'''Convert a date in Henning's reformed calendar to Julian Days.'''
tithi = int(tithi) - 1 # subtract 1 because computers count from 0
month = str(month)
year = int(year)
if(month[:4] == "Leap"):
month = month[5:]
leap = True
else:
leap = False
equinox = solar_epoch + (year * trop_year)
jday = newmoon(moonof(equinox), tz) # losar
if( round( (moonof(trans((equinox + syn_month), 0, tz)) - jday) / syn_month) == 12):
# normal year
jday = jday + (MONTHNO[month] * syn_month)
else:
# leap year
m = 0 # number of the current month
z = 0 # ecliptic longitude of the next zhongqi, starting with the northward equinox
l = False # have we passed the leap month?
zhongqi = equinox # time of the next zhongqi, starting with the northward equinox
while( MONTHS[m] != month ):
if(l):
# we are past the leap month
m += 1
elif( moonof(jday + syn_month) < dayof(trans(zhongqi, z, tz))):
# this is the leap month
l = True
else:
m += 1
z += 30
zhongqi += st
jday += syn_month
if( (leap) and (not l) and ( moonof(jday + (2 * syn_month)) < dayof(trans((zhongqi + st), (z + 30), tz)) ) ):
# the user specified the leap month as opposed to the corresponding regular month
jday += syn_month
# finally, account for the tithis
jday = dayof(phasetime( (jday + (syn_month * Fraction(tithi, 30))), (tithi * 12), tz))
return jday