1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 from timelinelib.calendar.pharaonic.time import PharaonicDelta
19 from timelinelib.calendar.pharaonic.time import PharaonicTime
20
21
22 FIRST_DAY = 1448638
26
27 - def __init__(self, year, month, day, hour, minute, second):
28 if not is_valid(year, month, day):
29 raise ValueError("Invalid pharaonic date %s-%s-%s" % (year, month, day))
30 self.year = year
31 self.month = month
32 self.day = day
33 self.hour = hour
34 self.minute = minute
35 self.second = second
36
38 return (isinstance(other, self.__class__) and
39 self.to_tuple() == other.to_tuple())
40
42 return not (self == other)
43
44 @classmethod
46 return cls(year, month, day, 0, 0, 0)
47
48 @classmethod
53
54
55 @property
57
58 if self.month == 13:
59 return 0
60
61 length_of_week = 10
62 days_into_year = ((self.month - 1)*30) + self.day
63
64 if self.day % length_of_week > 0:
65 return (days_into_year // length_of_week) + 1
66
67 return days_into_year // length_of_week
68
71
72 - def replace(self, year=None, month=None):
73 if year is None:
74 year = self.year
75 if month is None:
76 month = self.month
77 return self.__class__(
78 year,
79 month,
80 self.day,
81 self.hour,
82 self.minute,
83 self.second
84 )
85
88
90 return (self.year, self.month, self.day, self.hour, self.minute,
91 self.second)
92
94 return (self.year, self.month, self.day)
95
97 return (self.hour, self.minute, self.second)
98
103
105 return (self.month == 1 and
106 self.day == 1 and
107 self.hour == 0 and
108 self.minute == 0 and
109 self.second == 0)
110
112 return (self.day == 1 and
113 self.hour == 0 and
114 self.minute == 0 and
115 self.second == 0)
116
118 return "PharaonicDateTime<%d-%02d-%02d %02d:%02d:%02d>" % self.to_tuple()
119
121 if month <= 12:
122 return 30
123 else:
124 return 5
125
128 return (
129 hour >= 0 and hour < 24 and
130 minute >= 0 and minute < 60 and
131 second >= 0 and second < 60
132 )
133
136 return month >= 1 and month <= 13 and day >= 1 and day <= days_in_month(year, month)
137
140 """
141 This calendar calculation was originally published in Explanatory Supplement to the Astronomical Almanac, S.E. Urban and P.K. Seidelman, Eds. (2012). You can purchase the book at uscibooks.com/urban.htm. "15.11 Calendar Conversion Algorithms" from the following pdf is used in the below code. https://aa.usno.navy.mil/publications/docs/c15_usb_online.pdf
142 """
143 if julian_day < PharaonicTime.MIN_JULIAN_DAY:
144 raise ValueError("pharaonic_day_to_gregorian_ymd only works for julian days >= %d, but was %d" % (PharaonicTime.MIN_JULIAN_DAY, julian_day))
145
146 y = 3968
147 j = 47
148 m = 0
149 n = 13
150 r = 1
151 p = 365
152 q = 0
153 v = 0
154 u = 1
155 s = 30
156 t = 0
157 w = 0
158
159 f = julian_day + j
160 e = r * f + v
161 g = (e % p)//r
162 h = u * g + w
163 day = ((h % s)/u) + 1
164 month = (((h // s) + m) % n) + 1
165 year = (e // p) - y + (n + m - month)//n
166 return (year, month, day)
167
170 """
171 Pharaonic year 1 = Julian day 1448638
172 """
173
174 y = 3968
175 j = 47
176 m = 0
177 n = 13
178 r = 1
179 p = 365
180 q = 0
181 v = 0
182 u = 1
183 s = 30
184 t = 0
185 w = 0
186
187 h = month - m
188 g = year + y - (n-h)//n
189 f = (h - 1 + n) % n
190 e = (p * g + q)//r + day - 1 -j
191 julian_day = e + (s * f + t)//u
192
193 if julian_day < PharaonicTime.MIN_JULIAN_DAY:
194 raise ValueError("pharaonic_ymd_to_julian_day only works for julian days >= %d, but was %d" % (PharaonicTime.MIN_JULIAN_DAY, julian_day))
195 return julian_day
196