1515# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717#
18- # $Id: date.py,v 1.93 2007-12-21 11:21:08 richard Exp $
18+ # $Id: date.py,v 1.94 2007-12-23 00:23:23 richard Exp $
1919
2020"""Date, time and time interval handling.
2121"""
3333
3434from roundup import i18n
3535
36- def _add_granularity (src , order , value = 1 ):
37- '''Increment first non-None value in src dictionary ordered by 'order'
38- parameter
39- '''
40- for gran in order :
41- if src [gran ]:
42- src [gran ] = int (src [gran ]) + value
43- # XXX test and handle other cases
44- if gran == 'm' and src ['m' ] > 12 :
45- y , m = divmod (src ['m' ], 12 )
46- src ['m' ] = m
47- src ['y' ] = int (src ['y' ]) + y
48- break
49-
5036# no, I don't know why we must anchor the date RE when we only ever use it
5137# in a match()
5238date_re = re .compile (r'''^
@@ -248,7 +234,8 @@ class Date:
248234 <Date 2003-07-01.00:00:0.000000>
249235 '''
250236
251- def __init__ (self , spec = '.' , offset = 0 , add_granularity = 0 , translator = i18n ):
237+ def __init__ (self , spec = '.' , offset = 0 , add_granularity = False ,
238+ translator = i18n ):
252239 """Construct a date given a specification and a time zone offset.
253240
254241 'spec'
@@ -286,7 +273,7 @@ def __init__(self, spec='.', offset=0, add_granularity=0, translator=i18n):
286273 raise ValueError , 'Unknown spec %r' % (spec ,)
287274
288275 def set (self , spec , offset = 0 , date_re = date_re ,
289- serialised_re = serialised_date_re , add_granularity = 0 ):
276+ serialised_re = serialised_date_re , add_granularity = False ):
290277 ''' set the date to the value in spec
291278 '''
292279
@@ -308,8 +295,19 @@ def set(self, spec, offset=0, date_re=date_re,
308295
309296 info = m .groupdict ()
310297
298+ # determine whether we need to add anything at the end
311299 if add_granularity :
312- _add_granularity (info , 'SMHdmyab' )
300+ for gran in 'SMHdmy' :
301+ if info [gran ] is not None :
302+ if gran == 'S' :
303+ raise ValueError
304+ elif gran == 'M' :
305+ add_granularity = Interval ('00:01' )
306+ elif gran == 'H' :
307+ add_granularity = Interval ('01:00' )
308+ else :
309+ add_granularity = Interval ('+1%s' % gran )
310+ break
313311
314312 # get the current date as our default
315313 dt = datetime .datetime .utcnow ()
@@ -347,8 +345,6 @@ def set(self, spec, offset=0, date_re=date_re,
347345 # now handle the adjustment of hour
348346 frac = S - int (S )
349347 dt = datetime .datetime (y ,m ,d ,H ,M ,int (S ), int (frac * 1000000. ))
350- if add_granularity :
351- dt = dt - datetime .timedelta (seconds = 1 )
352348 y , m , d , H , M , S , x , x , x = dt .timetuple ()
353349 if adjust :
354350 y , m , d , H , M , S = _local_to_utc (y , m , d , H , M , S , offset )
@@ -365,6 +361,11 @@ def set(self, spec, offset=0, date_re=date_re,
365361 '"yyyy-mm-dd", "mm-dd", "HH:MM", "HH:MM:SS" or '
366362 '"yyyy-mm-dd.HH:MM:SS.SSS"' )% (spec ,)
367363
364+ # adjust by added granularity
365+ if add_granularity :
366+ self .applyInterval (add_granularity )
367+ self .applyInterval (Interval ('- 00:00:01' ))
368+
368369 def addInterval (self , interval ):
369370 ''' Add the interval to this date, returning the date tuple
370371 '''
@@ -616,7 +617,7 @@ class Interval:
616617
617618 TODO: more examples, showing the order of addition operation
618619 '''
619- def __init__ (self , spec , sign = 1 , allowdate = 1 , add_granularity = 0 ,
620+ def __init__ (self , spec , sign = 1 , allowdate = 1 , add_granularity = False ,
620621 translator = i18n
621622 ):
622623 """Construct an interval given a specification."""
@@ -658,7 +659,7 @@ def set(self, spec, allowdate=1, interval_re=re.compile('''
658659 )?''' , re .VERBOSE ), serialised_re = re .compile ('''
659660 (?P<s>[+-])?1?(?P<y>([ ]{3}\d|\d{4}))(?P<m>\d{2})(?P<d>\d{2})
660661 (?P<H>\d{2})(?P<M>\d{2})(?P<S>\d{2})''' , re .VERBOSE ),
661- add_granularity = 0 ):
662+ add_granularity = False ):
662663 ''' set the date to the value in spec
663664 '''
664665 self .year = self .month = self .week = self .day = self .hour = \
@@ -676,7 +677,10 @@ def set(self, spec, allowdate=1, interval_re=re.compile('''
676677 # pull out all the info specified
677678 info = m .groupdict ()
678679 if add_granularity :
679- _add_granularity (info , 'SMHdwmy' , (info ['s' ]== '-' and - 1 or 1 ))
680+ for gran in 'SMHdwmy' :
681+ if info [gran ] is not None :
682+ info [gran ] = int (info [gran ]) + (info ['s' ]== '-' and - 1 or 1 )
683+ break
680684
681685 valid = 0
682686 for group , attr in {'y' :'year' , 'm' :'month' , 'w' :'week' , 'd' :'day' ,
@@ -1007,7 +1011,7 @@ class Range:
10071011 <Range from None to 2003-03-09.20:00:00>
10081012
10091013 """
1010- def __init__ (self , spec , Type , allow_granularity = 1 , ** params ):
1014+ def __init__ (self , spec , Type , allow_granularity = True , ** params ):
10111015 """Initializes Range of type <Type> from given <spec> string.
10121016
10131017 Sets two properties - from_value and to_value. None assigned to any of
@@ -1016,28 +1020,27 @@ def __init__(self, spec, Type, allow_granularity=1, **params):
10161020
10171021 The Type parameter here should be class itself (e.g. Date), not a
10181022 class instance.
1019-
10201023 """
10211024 self .range_type = Type
10221025 re_range = r'(?:^|from(.+?))(?:to(.+?)$|$)'
10231026 re_geek_range = r'(?:^|(.+?));(?:(.+?)$|$)'
10241027 # Check which syntax to use
1025- if spec .find (';' ) == - 1 :
1026- # Native english
1027- mch_range = re .search (re_range , spec .strip (), re .IGNORECASE )
1028- else :
1028+ if ';' in spec :
10291029 # Geek
1030- mch_range = re .search (re_geek_range , spec .strip ())
1031- if mch_range :
1032- self .from_value , self .to_value = mch_range .groups ()
1030+ m = re .search (re_geek_range , spec .strip ())
1031+ else :
1032+ # Native english
1033+ m = re .search (re_range , spec .strip (), re .IGNORECASE )
1034+ if m :
1035+ self .from_value , self .to_value = m .groups ()
10331036 if self .from_value :
10341037 self .from_value = Type (self .from_value .strip (), ** params )
10351038 if self .to_value :
10361039 self .to_value = Type (self .to_value .strip (), ** params )
10371040 else :
10381041 if allow_granularity :
10391042 self .from_value = Type (spec , ** params )
1040- self .to_value = Type (spec , add_granularity = 1 , ** params )
1043+ self .to_value = Type (spec , add_granularity = True , ** params )
10411044 else :
10421045 raise ValueError , "Invalid range"
10431046
0 commit comments