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…
Reference in New Issue