summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: cfbb968)
raw | patch | inline | side by side (parent: cfbb968)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Wed, 19 Mar 2003 05:18:11 +0000 (05:18 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Wed, 19 Mar 2003 05:18:11 +0000 (05:18 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1609 57a73879-2fb5-44c3-a270-3262357dd7e2
CHANGES.txt | patch | blob | history | |
roundup/date.py | patch | blob | history | |
test/test_dates.py | patch | blob | history |
diff --git a/CHANGES.txt b/CHANGES.txt
index 8a3ae62b25b9ccdaffc0bd128ef072b426623409..e91d50932f76a6742e9657f7355d0d40cf2750ba 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
chapter "Searching Page" for details)
- role names made case insensitive
- added ability to restore retired nodes
+- more lenient date input and addition Interval input support (sf bug 677764)
Fixed:
diff --git a/roundup/date.py b/roundup/date.py
index 2654a03b665040455d71453581a28866a915c083..165a883ed2aebe4f4c428e6acbf389bf62464e76 100644 (file)
--- a/roundup/date.py
+++ b/roundup/date.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: date.py,v 1.49 2003-03-19 03:25:30 richard Exp $
+# $Id: date.py,v 1.50 2003-03-19 05:18:10 richard Exp $
__doc__ = """
Date, time and time interval handling.
self.second, x, x, x = time.gmtime(ts)
def set(self, spec, offset=0, date_re=re.compile(r'''
- (((?P<y>\d\d\d\d)-)?(?P<m>\d\d?)?-(?P<d>\d\d?))? # [yyyy-]mm-dd
+ (((?P<y>\d\d\d\d)[/-])?(?P<m>\d\d?)?[/-](?P<d>\d\d?))? # [yyyy-]mm-dd
(?P<n>\.)? # .
(((?P<H>\d?\d):(?P<M>\d\d))?(:(?P<S>\d\d))?)? # hh:mm:ss
(?P<o>.+)? # offset
if info.get('o', None):
try:
- self.applyInterval(Interval(info['o']))
+ self.applyInterval(Interval(info['o'], allowdate=0))
except ValueError:
raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].'
'[[h]h:mm[:ss]][offset]')
<Interval + 6m>
>>> Interval('1:00')/2
<Interval + 0:30>
+ >>> Interval('2003-03-18')
+ <Interval + [number of days between now and 2003-03-18]>
+ >>> Interval('-4d 2003-03-18')
+ <Interval + [number of days between now and 2003-03-14]>
Interval arithmetic is handled in a couple of special ways, trying
to cater for the most common cases. Fundamentally, Intervals which
TODO: more examples, showing the order of addition operation
'''
- def __init__(self, spec, sign=1):
+ def __init__(self, spec, sign=1, allowdate=1):
"""Construct an interval given a specification."""
if type(spec) == type(''):
- self.set(spec)
+ self.set(spec, allowdate)
else:
if len(spec) == 7:
self.sign, self.year, self.month, self.day, self.hour, \
self.year, self.month, self.day, self.hour, self.minute, \
self.second = spec
- def set(self, spec, interval_re=re.compile('''
+ def set(self, spec, allowdate=1, interval_re=re.compile('''
\s*(?P<s>[-+])? # + or -
\s*((?P<y>\d+\s*)y)? # year
\s*((?P<m>\d+\s*)m)? # month
\s*((?P<w>\d+\s*)w)? # week
\s*((?P<d>\d+\s*)d)? # day
\s*(((?P<H>\d+):(?P<M>\d+))?(:(?P<S>\d+))?)? # time
- \s*''', re.VERBOSE), serialised_re=re.compile('''
+ \s*(?P<D>
+ (\d\d\d\d[/-])?(\d\d?)?[/-](\d\d?)? # [yyyy-]mm-dd
+ \.? # .
+ (\d?\d:\d\d)?(:\d\d)? # hh:mm:ss
+ )?''', re.VERBOSE), serialised_re=re.compile('''
(?P<s>[+-])?1?(?P<y>([ ]{3}\d|\d{4}))(?P<m>\d{2})(?P<d>\d{2})
(?P<H>\d{2})(?P<M>\d{2})(?P<S>\d{2})''', re.VERBOSE)):
''' set the date to the value in spec
m = interval_re.match(spec)
if not m:
raise ValueError, _('Not an interval spec: [+-] [#y] [#m] [#w] '
- '[#d] [[[H]H:MM]:SS]')
+ '[#d] [[[H]H:MM]:SS] [date spec]')
+ # pull out all the info specified
info = m.groupdict()
valid = 0
for group, attr in {'y':'year', 'm':'month', 'w':'week', 'd':'day',
valid = 1
setattr(self, attr, int(info[group]))
- if not valid:
+ # make sure it's valid
+ if not valid and not info['D']:
raise ValueError, _('Not an interval spec: [+-] [#y] [#m] [#w] '
'[#d] [[[H]H:MM]:SS]')
if info['s'] is not None:
self.sign = {'+':1, '-':-1}[info['s']]
+ # use a date spec if one is given
+ if allowdate and info['D'] is not None:
+ now = Date('.')
+ date = Date(info['D'])
+ # if no time part was specified, nuke it in the "now" date
+ if not date.hour or date.minute or date.second:
+ now.hour = now.minute = now.second = 0
+ if date != now:
+ y = now - (date + self)
+ self.__init__(y.get_tuple())
+
def __cmp__(self, other):
"""Compare this interval to another interval."""
if other is None:
diff --git a/test/test_dates.py b/test/test_dates.py
index 44f3f1023d7384b973346ae27df2b2abba79704f..fcd1d1d656dcb121a9fd6a47df98c1cc6a9868b4 100644 (file)
--- a/test/test_dates.py
+++ b/test/test_dates.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_dates.py,v 1.21 2003-03-19 03:25:30 richard Exp $
+# $Id: test_dates.py,v 1.22 2003-03-19 05:18:11 richard Exp $
import unittest, time
ae = self.assertEqual
date = Date("2000-04-17")
ae(str(date), '2000-04-17.00:00:00')
+ date = Date("2000/04/17")
+ ae(str(date), '2000-04-17.00:00:00')
date = Date("2000-4-7")
ae(str(date), '2000-04-07.00:00:00')
date = Date("2000-4-17")
ae(str(date), '%s-01-25.00:00:00'%y)
date = Date("2000-04-17.03:45")
ae(str(date), '2000-04-17.03:45:00')
+ date = Date("2000/04/17.03:45")
+ ae(str(date), '2000-04-17.03:45:00')
date = Date("08-13.22:13")
ae(str(date), '%s-08-13.22:13:00'%y)
date = Date("11-07.09:32:43")
ae(str(Interval(' 14:00 ')), '+ 14:00')
ae(str(Interval(' 0:04:33 ')), '+ 0:04:33')
+ def testIntervalInitDate(self):
+ ae = self.assertEqual
+ now = Date('.')
+ now.hour = now.minute = now.second = 0
+ then = now + Interval('2d')
+ ae(str(Interval(str(then))), '+ 2d')
+ then = now - Interval('2d')
+ ae(str(Interval(str(then))), '- 2d')
+
def testIntervalAdd(self):
ae = self.assertEqual
ae(str(Interval('1y') + Interval('1y')), '+ 2y')