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__ = """
2121Date, 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 :
0 commit comments