# Simple date
class
import re
patt
= "[/.,; ]"
class Dates(object):
monthDict
= dict(zip(range(1,13),['January', 'February',
'March', 'April', \
'May',
'June', 'July', 'August', 'September', \
'October', 'November', 'December']))
daysList1 = [31,28,31,30,31,30,31,31,30,31,30,31]
daysList2 =
[31,29,31,30,31,30,31,31,30,31,30,31]
def __init__(self,
dateStr):
# dateStr
is in the format month/day/year (xx/xx/xxxx) or month.day.year
self.dateStr
= dateStr
try:
self.month,
self.day, self.year = [int(s) for s in re.split(patt, dateStr)]
except:
raise ValueError, "Invalid date format"
self.month_str
= self.monthStr()
self.day_num
= self.dayNo()
def isLeap(self, yr):
if not yr % 4:
return 1
return 0
def daysList(self, year):
return
[self.daysList1, self.daysList2][self.isLeap(year)]
def monthStr(self):
# return the
text representation of the month number
try:
return self.monthDict[self.month]
except KeyError:
raise ValueError, "Invalid month number"
def dayNo(self):
# return the
day number in the year
if self.day < 1 or self.day > self.daysList(self.year)[self.month-1]:
raise ValueError, "Invalid day number"
return sum(self.daysList(self.year)[:self.month-1])
+ self.day
def monthDayYr(self, day_num):
# return a
tuple of month, day, year given a day number
# day number
is with respect to the year of the instance
idx
= 0
year = self.year
while day_num < 1:
day_num
+= sum(self.daysList(year))
year -= 1
while True:
if day_num <= self.daysList(year)[idx]:
return
idx+1, day_num, year
day_num
-= self.daysList(year)[idx]
idx += 1
if idx == 12:
idx = 0
year
+= 1
def nextDay(self):
return self+1
def preDay(self):
return self-1
def daysToZero(self):
# calculate the number of days with
respect to year 0
if self.year < 0:
yrList = xrange(self.year, 0)
days = -self.dayNo()
else:
yrList = xrange(0, self.year)
days = self.dayNo()
return days +
sum([sum(self.daysList(yr)) for yr in yrList])
def diff(self,
other):
year_diff = self.year - other.year
if year_diff < 0:
yrList
= xrange(self.year, other.year)
days = self.dayNo() - other.dayNo()
else:
yrList = xrange(other.year, self.year)
days = other.dayNo() - self.dayNo()
return days -
sum([sum(self.daysList(yr)) for yr in yrList])
def __add__(self,
days):
return
Dates('/'.join([str(item) for item in self.monthDayYr(self.dayNo() +
days)]))
def __sub__(self,
days):
# days can be
an int or a Dates() object
# return a
Dates() object, or the number of days difference
if isinstance(days, int):
return
Dates('/'.join([str(item) for item in self.monthDayYr(self.dayNo() -
days)]))
# days is an
instance of Dates if not an int
return self.daysToZero()-days.daysToZero()
def __str__(self):
return
"%s %d, %d" % (self.month_str, self.day, self.year)
if __name__ == '__main__':
a = Dates('6/8/2007')
print a
print a.nextDay()
print a.preDay()
b = a+90039
print b
c = a-4665
print c
d = Dates('12/31/2000')
print d.dayNo()
f = Dates('2.29.2000')
print f
print f.isLeap(f.year)
print f.daysList(f.year)
print f-d
print f.diff(d)
print d.diff(f)
print a-b
print a.diff(b)
print b-a
print b.diff(a)
'''
>>>
366
1
[31, 29, 31, 30,
31, 30, 31, 31, 30, 31, 30, 31]
-306
-306
306
-90039
-90039
90039
90039
>>> >>>
a = Dates('12/31/2007')
>>> b = Dates('12/31/2006')
>>> c = Dates('12/31/2005')
>>> d = Dates('12/31/2004')
>>> e = Dates('12/31/2008')
>>> f = Dates('12/31/2003')
>>> a-b
365
>>> e-a
366
>>> e-f
1827
>>>
1827%365
2
>>> a-e
-366
>>> f-e
-1827
>>>
'''