-
Notifications
You must be signed in to change notification settings - Fork 1
/
util.py
190 lines (167 loc) · 5.65 KB
/
util.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#! /usr/bin/env python
"""
util:
Collection of utilities, classes, functions for workcal.py
"""
#
# Copyright (c) 2012 Len Tanaka
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from datetime import date, time, timedelta, tzinfo
class HST(tzinfo):
def utcoffset(self, dt):
return timedelta(hours=-10)
def dst(self, dt):
return timedelta(hours=-10)
def tzname(self, dt):
return 'US/Hawaii'
class GMT(tzinfo):
def utcoffset(self, dt):
return timedelta(0)
def dst(self, dt):
return timedelta(0)
def tzname(self, dt):
return 'UTC'
class Event:
"""Event object: represents basic elements of subject and start date"""
subject = ''
date = date.today()
def __init__(self, subject, date):
self.subject = subject
self.date = date
def __repr__(self):
return ("{self.subject},{self.date:%m/%d/%y}".format(self=self))
class GCalEvent(Event):
"""Extends Event object to Google Calendar data:
Subject,Start Date,Start Time,End Date,End Time,All Day Event,
Description,Location,Private"""
#subject inherited
startdate = Event.date
starttime = ''
enddate = ''
endtime = ''
alldayevent = False
description = ''
location = '' #Future geolocation info
private = ''
def __init__(self, subject, date):
self.subject = subject
self.startdate = date
#Other attributes are optional
def __repr__(self):
if self.alldayevent:
return ("{self.subject},"
"{self.startdate:%m/%d/%y},"
",,,,"
"{self.description},"
"{self.location},".format(self=self))
else:
return ("{self.subject},"
"{self.startdate:%m/%d/%y},"
"{self.starttime:%H:%M},"
"{self.enddate:%m/%d/%y},"
"{self.endtime:%H:%M},"
"{self.alldayevent},"
"{self.description},"
"{self.location},"
"{self.private}".format(self=self))
class PersonEvent:
"""Event attached to particular person"""
person = ''
event = ''
def __init__(self, name, event):
self.person = name
self.event = event #from Event or GCalEvent
def __repr__(self):
return ("{self.person}-{self.event}".format(self=self))
def calcEaster(year):
"""Calculate the date of Easter
from: http://www.oremus.org/liturgy/etc/ktf/app/easter.html
param year
returns date tuple (day, month, year)
"""
gold = year % 19 + 1
sol = (year - 1600) // 100 - (year - 1600) // 400
lun = (((year - 1400) // 100) * 8) // 25
_pasch = (3 - 11 * gold + sol - lun) % 30
if (_pasch == 29) or (_pasch == 28 and gold > 11):
pasch = _pasch - 1
else:
pasch = _pasch
dom = (year + (year // 4) - (year // 100) + (year // 400)) % 7
easter = pasch + 1 + (4 - dom - pasch) % 7
if easter < 11:
return (easter + 21, 3, year)
else:
return (easter - 10, 4, year)
def EasterDate(year):
"""EASTER DATE CALCULATION FOR YEARS 1583 TO 4099
This algorithm is an arithmetic interpretation of the 3 step
Easter Dating Method developed by Ron Mallen 1985, as a vast
improvement on the method described in the Common Prayer Book
from: https://www.assa.org.au/edm
param year
returns date tuple (day, month, year)
"""
FirstDig = year // 100
Remain19 = year % 19
# calculate PFM date
temp = (FirstDig - 15) // 2 + 202 - 11 * Remain19
def f(x):
return {
21: temp - 1,
24: temp - 1,
25: temp - 1,
27: temp - 1,
28: temp - 1,
29: temp - 1,
30: temp - 1,
31: temp - 1,
32: temp - 1,
34: temp - 1,
35: temp - 1,
38: temp - 1,
33: temp - 2,
36: temp - 2,
37: temp - 2,
39: temp - 2,
40: temp - 2,
}.get(x, temp)
temp = f(FirstDig)
temp = temp % 30
tA = temp + 21
if temp == 29:
tA = tA - 1
if (temp == 28) and (Remain19 > 10):
tA = tA - 1
# find the next Sunday
tB = (tA - 19) % 7
tC = (40 - FirstDig) % 4
if tC == 3:
tC = tC + 1
if tC > 1:
tC = tC + 1
temp = year % 100
tD = (temp + temp // 4) % 7
tE = ((20 - tB - tC - tD) % 7) + 1
d = tA + tE
if d > 31:
return (d-31, 4, year)
else:
return (d, 3, year)