Skip to content

Commit 934e3ba

Browse files
author
Richard Jones
committed
more lenient date input and addition Interval input support [SF#677764]
1 parent 6753f98 commit 934e3ba

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Feature:
5050
chapter "Searching Page" for details)
5151
- role names made case insensitive
5252
- added ability to restore retired nodes
53+
- more lenient date input and addition Interval input support (sf bug 677764)
5354

5455

5556
Fixed:

roundup/date.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: date.py,v 1.49 2003-03-19 03:25:30 richard Exp $
18+
# $Id: date.py,v 1.50 2003-03-19 05:18:10 richard Exp $
1919

2020
__doc__ = """
2121
Date, time and time interval handling.
@@ -96,7 +96,7 @@ def __init__(self, spec='.', offset=0):
9696
self.second, x, x, x = time.gmtime(ts)
9797

9898
def set(self, spec, offset=0, date_re=re.compile(r'''
99-
(((?P<y>\d\d\d\d)-)?(?P<m>\d\d?)?-(?P<d>\d\d?))? # [yyyy-]mm-dd
99+
(((?P<y>\d\d\d\d)[/-])?(?P<m>\d\d?)?[/-](?P<d>\d\d?))? # [yyyy-]mm-dd
100100
(?P<n>\.)? # .
101101
(((?P<H>\d?\d):(?P<M>\d\d))?(:(?P<S>\d\d))?)? # hh:mm:ss
102102
(?P<o>.+)? # offset
@@ -147,7 +147,7 @@ def set(self, spec, offset=0, date_re=re.compile(r'''
147147

148148
if info.get('o', None):
149149
try:
150-
self.applyInterval(Interval(info['o']))
150+
self.applyInterval(Interval(info['o'], allowdate=0))
151151
except ValueError:
152152
raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].'
153153
'[[h]h:mm[:ss]][offset]')
@@ -321,6 +321,10 @@ class Interval:
321321
<Interval + 6m>
322322
>>> Interval('1:00')/2
323323
<Interval + 0:30>
324+
>>> Interval('2003-03-18')
325+
<Interval + [number of days between now and 2003-03-18]>
326+
>>> Interval('-4d 2003-03-18')
327+
<Interval + [number of days between now and 2003-03-14]>
324328
325329
Interval arithmetic is handled in a couple of special ways, trying
326330
to cater for the most common cases. Fundamentally, Intervals which
@@ -341,10 +345,10 @@ class Interval:
341345
342346
TODO: more examples, showing the order of addition operation
343347
'''
344-
def __init__(self, spec, sign=1):
348+
def __init__(self, spec, sign=1, allowdate=1):
345349
"""Construct an interval given a specification."""
346350
if type(spec) == type(''):
347-
self.set(spec)
351+
self.set(spec, allowdate)
348352
else:
349353
if len(spec) == 7:
350354
self.sign, self.year, self.month, self.day, self.hour, \
@@ -355,14 +359,18 @@ def __init__(self, spec, sign=1):
355359
self.year, self.month, self.day, self.hour, self.minute, \
356360
self.second = spec
357361

358-
def set(self, spec, interval_re=re.compile('''
362+
def set(self, spec, allowdate=1, interval_re=re.compile('''
359363
\s*(?P<s>[-+])? # + or -
360364
\s*((?P<y>\d+\s*)y)? # year
361365
\s*((?P<m>\d+\s*)m)? # month
362366
\s*((?P<w>\d+\s*)w)? # week
363367
\s*((?P<d>\d+\s*)d)? # day
364368
\s*(((?P<H>\d+):(?P<M>\d+))?(:(?P<S>\d+))?)? # time
365-
\s*''', re.VERBOSE), serialised_re=re.compile('''
369+
\s*(?P<D>
370+
(\d\d\d\d[/-])?(\d\d?)?[/-](\d\d?)? # [yyyy-]mm-dd
371+
\.? # .
372+
(\d?\d:\d\d)?(:\d\d)? # hh:mm:ss
373+
)?''', re.VERBOSE), serialised_re=re.compile('''
366374
(?P<s>[+-])?1?(?P<y>([ ]{3}\d|\d{4}))(?P<m>\d{2})(?P<d>\d{2})
367375
(?P<H>\d{2})(?P<M>\d{2})(?P<S>\d{2})''', re.VERBOSE)):
368376
''' set the date to the value in spec
@@ -375,8 +383,9 @@ def set(self, spec, interval_re=re.compile('''
375383
m = interval_re.match(spec)
376384
if not m:
377385
raise ValueError, _('Not an interval spec: [+-] [#y] [#m] [#w] '
378-
'[#d] [[[H]H:MM]:SS]')
386+
'[#d] [[[H]H:MM]:SS] [date spec]')
379387

388+
# pull out all the info specified
380389
info = m.groupdict()
381390
valid = 0
382391
for group, attr in {'y':'year', 'm':'month', 'w':'week', 'd':'day',
@@ -385,7 +394,8 @@ def set(self, spec, interval_re=re.compile('''
385394
valid = 1
386395
setattr(self, attr, int(info[group]))
387396

388-
if not valid:
397+
# make sure it's valid
398+
if not valid and not info['D']:
389399
raise ValueError, _('Not an interval spec: [+-] [#y] [#m] [#w] '
390400
'[#d] [[[H]H:MM]:SS]')
391401

@@ -395,6 +405,17 @@ def set(self, spec, interval_re=re.compile('''
395405
if info['s'] is not None:
396406
self.sign = {'+':1, '-':-1}[info['s']]
397407

408+
# use a date spec if one is given
409+
if allowdate and info['D'] is not None:
410+
now = Date('.')
411+
date = Date(info['D'])
412+
# if no time part was specified, nuke it in the "now" date
413+
if not date.hour or date.minute or date.second:
414+
now.hour = now.minute = now.second = 0
415+
if date != now:
416+
y = now - (date + self)
417+
self.__init__(y.get_tuple())
418+
398419
def __cmp__(self, other):
399420
"""Compare this interval to another interval."""
400421
if other is None:

test/test_dates.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: test_dates.py,v 1.21 2003-03-19 03:25:30 richard Exp $
18+
# $Id: test_dates.py,v 1.22 2003-03-19 05:18:11 richard Exp $
1919

2020
import unittest, time
2121

@@ -35,6 +35,8 @@ def testDate(self):
3535
ae = self.assertEqual
3636
date = Date("2000-04-17")
3737
ae(str(date), '2000-04-17.00:00:00')
38+
date = Date("2000/04/17")
39+
ae(str(date), '2000-04-17.00:00:00')
3840
date = Date("2000-4-7")
3941
ae(str(date), '2000-04-07.00:00:00')
4042
date = Date("2000-4-17")
@@ -44,6 +46,8 @@ def testDate(self):
4446
ae(str(date), '%s-01-25.00:00:00'%y)
4547
date = Date("2000-04-17.03:45")
4648
ae(str(date), '2000-04-17.03:45:00')
49+
date = Date("2000/04/17.03:45")
50+
ae(str(date), '2000-04-17.03:45:00')
4751
date = Date("08-13.22:13")
4852
ae(str(date), '%s-08-13.22:13:00'%y)
4953
date = Date("11-07.09:32:43")
@@ -162,6 +166,15 @@ def testIntervalInit(self):
162166
ae(str(Interval(' 14:00 ')), '+ 14:00')
163167
ae(str(Interval(' 0:04:33 ')), '+ 0:04:33')
164168

169+
def testIntervalInitDate(self):
170+
ae = self.assertEqual
171+
now = Date('.')
172+
now.hour = now.minute = now.second = 0
173+
then = now + Interval('2d')
174+
ae(str(Interval(str(then))), '+ 2d')
175+
then = now - Interval('2d')
176+
ae(str(Interval(str(then))), '- 2d')
177+
165178
def testIntervalAdd(self):
166179
ae = self.assertEqual
167180
ae(str(Interval('1y') + Interval('1y')), '+ 2y')

0 commit comments

Comments
 (0)