Allow to use relative dates in the format (now|today)[+-][0-9](day|week|month|year)(s)? (Closes #137)
Also fix DateRange not accepting ranges of one day.
This commit is contained in:
		
							parent
							
								
									a11ea50319
								
							
						
					
					
						commit
						37254abc36
					
				@ -105,7 +105,7 @@ class TestUtil(unittest.TestCase):
 | 
				
			|||||||
        self.assertTrue("19690721" in _ac)
 | 
					        self.assertTrue("19690721" in _ac)
 | 
				
			||||||
        _firstmilenium = DateRange(end="10000101")
 | 
					        _firstmilenium = DateRange(end="10000101")
 | 
				
			||||||
        self.assertTrue("07110427" in _firstmilenium)
 | 
					        self.assertTrue("07110427" in _firstmilenium)
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    def test_unified_dates(self):
 | 
					    def test_unified_dates(self):
 | 
				
			||||||
        self.assertEqual(unified_strdate('December 21, 2010'), '20101221')
 | 
					        self.assertEqual(unified_strdate('December 21, 2010'), '20101221')
 | 
				
			||||||
        self.assertEqual(unified_strdate('8/7/2009'), '20090708')
 | 
					        self.assertEqual(unified_strdate('8/7/2009'), '20090708')
 | 
				
			||||||
 | 
				
			|||||||
@ -586,7 +586,29 @@ def unified_strdate(date_str):
 | 
				
			|||||||
    return upload_date
 | 
					    return upload_date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def date_from_str(date_str):
 | 
					def date_from_str(date_str):
 | 
				
			||||||
    """Return a datetime object from a string in the format YYYYMMDD"""
 | 
					    """
 | 
				
			||||||
 | 
					    Return a datetime object from a string in the format YYYYMMDD or
 | 
				
			||||||
 | 
					    (now|today)[+-][0-9](day|week|month|year)(s)?"""
 | 
				
			||||||
 | 
					    today = datetime.date.today()
 | 
				
			||||||
 | 
					    if date_str == 'now'or date_str == 'today':
 | 
				
			||||||
 | 
					        return today
 | 
				
			||||||
 | 
					    match = re.match('(now|today)(?P<sign>[+-])(?P<time>\d+)(?P<unit>day|week|month|year)(s)?', date_str)
 | 
				
			||||||
 | 
					    if match is not None:
 | 
				
			||||||
 | 
					        sign = match.group('sign')
 | 
				
			||||||
 | 
					        time = int(match.group('time'))
 | 
				
			||||||
 | 
					        if sign == '-':
 | 
				
			||||||
 | 
					            time = -time
 | 
				
			||||||
 | 
					        unit = match.group('unit')
 | 
				
			||||||
 | 
					        #A bad aproximation?
 | 
				
			||||||
 | 
					        if unit == 'month':
 | 
				
			||||||
 | 
					            unit = 'day'
 | 
				
			||||||
 | 
					            time *= 30
 | 
				
			||||||
 | 
					        elif unit == 'year':
 | 
				
			||||||
 | 
					            unit = 'day'
 | 
				
			||||||
 | 
					            time *= 365
 | 
				
			||||||
 | 
					        unit += 's'
 | 
				
			||||||
 | 
					        delta = datetime.timedelta(**{unit: time})
 | 
				
			||||||
 | 
					        return today + delta
 | 
				
			||||||
    return datetime.datetime.strptime(date_str, "%Y%m%d").date()
 | 
					    return datetime.datetime.strptime(date_str, "%Y%m%d").date()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
class DateRange(object):
 | 
					class DateRange(object):
 | 
				
			||||||
@ -601,7 +623,7 @@ class DateRange(object):
 | 
				
			|||||||
            self.end = date_from_str(end)
 | 
					            self.end = date_from_str(end)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.end = datetime.datetime.max.date()
 | 
					            self.end = datetime.datetime.max.date()
 | 
				
			||||||
        if self.start >= self.end:
 | 
					        if self.start > self.end:
 | 
				
			||||||
            raise ValueError('Date range: "%s" , the start date must be before the end date' % self)
 | 
					            raise ValueError('Date range: "%s" , the start date must be before the end date' % self)
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def day(cls, day):
 | 
					    def day(cls, day):
 | 
				
			||||||
@ -609,7 +631,8 @@ class DateRange(object):
 | 
				
			|||||||
        return cls(day,day)
 | 
					        return cls(day,day)
 | 
				
			||||||
    def __contains__(self, date):
 | 
					    def __contains__(self, date):
 | 
				
			||||||
        """Check if the date is in the range"""
 | 
					        """Check if the date is in the range"""
 | 
				
			||||||
        date = date_from_str(date)
 | 
					        if not isinstance(date, datetime.date):
 | 
				
			||||||
        return self.start <= date and date <= self.end
 | 
					            date = date_from_str(date)
 | 
				
			||||||
 | 
					        return self.start <= date <= self.end
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return '%s - %s' % ( self.start.isoformat(), self.end.isoformat())
 | 
					        return '%s - %s' % ( self.start.isoformat(), self.end.isoformat())
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user