X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fdate.py;h=54265d170431c02edbb610749a3487a55f3e6515;hb=715f6d151e0a42146aeb9c64af875cae6bb946e6;hp=8e20c49ac0a54b911291256690e3179a126f5463;hpb=e8e0c9b06279ec296229fcbe2f1c308f4f67afb8;p=roundup.git diff --git a/roundup/date.py b/roundup/date.py index 8e20c49..54265d1 100644 --- a/roundup/date.py +++ b/roundup/date.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: date.py,v 1.26 2002-09-10 00:18:20 richard Exp $ +# $Id: date.py,v 1.36 2002-10-12 23:10:36 richard Exp $ __doc__ = """ Date, time and time interval handling. @@ -153,14 +153,15 @@ class Date: """ return Date(self.addInterval(interval)) - # XXX deviates from spec to allow subtraction of dates as well + # deviates from spec to allow subtraction of dates as well def __sub__(self, other): """ Subtract: 1. an interval from this date to produce another date. 2. a date from this date to produce an interval. """ if isinstance(other, Interval): - other = Interval(other.get_tuple(), sign=-other.sign) + other = Interval(other.get_tuple()) + other.sign *= -1 return self.__add__(other) assert isinstance(other, Date), 'May only subtract Dates or Intervals' @@ -205,31 +206,41 @@ class Date: return '%4d-%02d-%02d.%02d:%02d:%02d'%(self.year, self.month, self.day, self.hour, self.minute, self.second) - def pretty(self): + def pretty(self, format='%d %B %Y'): ''' print up the date date using a pretty format... + + Note that if the day is zero, and the day appears first in the + format, then the day number will be removed from output. ''' - str = time.strftime('%d %B %Y', (self.year, self.month, - self.day, self.hour, self.minute, self.second, 0, 0, 0)) - if str[0] == '0': return ' ' + str[1:] + str = time.strftime(format, (self.year, self.month, self.day, + self.hour, self.minute, self.second, 0, 0, 0)) + # handle zero day by removing it + if format.startswith('%d') and str[0] == '0': + return ' ' + str[1:] return str def set(self, spec, offset=0, date_re=re.compile(r''' (((?P\d\d\d\d)-)?((?P\d\d?)-(?P\d\d?))?)? # yyyy-mm-dd - (?P\.)? # . - (((?P\d?\d):(?P\d\d))?(:(?P\d\d))?)? # hh:mm:ss - (?P.+)? # offset - ''', re.VERBOSE), serialised_re=re.compile(''' - (?P\d{4})(?P\d{2})(?P\d{2}) # yyyymmdd - (?P\d{2})(?P\d{2})(?P\d{2}) # HHMMSS + (?P\.)? # . + (((?P\d?\d):(?P\d\d))?(:(?P\d\d))?)? # hh:mm:ss + (?P.+)? # offset + ''', re.VERBOSE), serialised_re=re.compile(r''' + (\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d) ''', re.VERBOSE)): ''' set the date to the value in spec ''' m = serialised_re.match(spec) - if not m: - m = date_re.match(spec) - if not m: - raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].' - '[[h]h:mm[:ss]][offset]') + if m is not None: + # we're serialised - easy! + self.year, self.month, self.day, self.hour, self.minute, \ + self.second = map(int, m.groups()[:6]) + return + + # not serialised data, try usual format + m = date_re.match(spec) + if m is None: + raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].' + '[[h]h:mm[:ss]][offset]') info = m.groupdict() @@ -315,9 +326,14 @@ class Interval: if type(spec) == type(''): self.set(spec) else: - self.sign = sign - self.year, self.month, self.day, self.hour, self.minute, \ - self.second = spec + if len(spec) == 7: + self.sign, self.year, self.month, self.day, self.hour, \ + self.minute, self.second = spec + else: + # old, buggy spec form + self.sign = sign + self.year, self.month, self.day, self.hour, self.minute, \ + self.second = spec def __cmp__(self, other): """Compare this interval to another interval.""" @@ -343,6 +359,22 @@ class Interval: l.append('%d:%02d'%(self.hour, self.minute)) return ' '.join(l) + def __add__(self, other): + if isinstance(other, Date): + # the other is a Date - produce a Date + return Date(other.addInterval(self)) + elif isinstance(other, Interval): + # add the other Interval to this one + a = self.get_tuple() + b = other.get_tuple() + if b[0] < 0: + i = Interval([x-y for x,y in zip(a[1:],b[1:])]) + else: + i = Interval([x+y for x,y in zip(a[1:],b[1:])]) + return i + # nope, no idea what to do with this other... + raise TypeError, "Can't add %r"%other + def set(self, spec, interval_re=re.compile(''' \s*(?P[-+])? # + or - \s*((?P\d+\s*)y)? # year @@ -351,7 +383,7 @@ class Interval: \s*((?P\d+\s*)d)? # day \s*(((?P\d+):(?P\d+))?(:(?P\d+))?)? # time \s*''', re.VERBOSE), serialised_re=re.compile(''' - (?P[+-])(?P\d{4})(?P\d{2})(?P\d{2}) + (?P[+-])?1?(?P([ ]{3}\d|\d{4}))(?P\d{2})(?P\d{2}) (?P\d{2})(?P\d{2})(?P\d{2})''', re.VERBOSE)): ''' set the date to the value in spec ''' @@ -435,7 +467,8 @@ class Interval: self.minute, self.second) def serialise(self): - return '%s%4d%02d%02d%02d%02d%02d'%(self.sign, self.year, self.month, + sign = self.sign > 0 and '+' or '-' + return '%s%04d%02d%02d%02d%02d%02d'%(sign, self.year, self.month, self.day, self.hour, self.minute, self.second)