Change relative date's format to further simplify it

A relative date doesn't need to be prefixed by @ anymore.
The relative date pattern now displays named groups.
Digits have been change to [0-9] to avoid other digit characters.
Removed the @ character in tests.
Updated subsequent documentation.
This commit is contained in:
euri10 2017-01-31 16:56:03 +01:00
parent f0aca5e0d3
commit d2cd4c0f21
3 changed files with 28 additions and 26 deletions

View file

@ -554,22 +554,25 @@ class Period(object):
relative.
An absolute date has to be like one of the date_formats '%Y' or '%Y-%m'
or '%Y-%m-%d'
A relative date begins by '@ 'and has to follow the pattern_dq format
'@([+|-]?)(\d+)([y|m|w|d])'
- '@' indicates it's a date relative to now()
- the optional '+' or '-' sign, which defaults to '+' will increment or
decrement now() by a certain quantity
- that quantity can be expressed in days, weeks, months or years
respectively 'd', 'w', 'm', 'y'
Please note that this relative calculation is rather approximate as it
makes the assumption of 30 days per month and 365 days per year
A relative date consists of three parts:
- a ``+`` or ``-`` sign is optional and defaults to ``+``. The ``+``
sign will add a time quantity to the current date while the ``-`` sign
will do the opposite
- a number follows and indicates the amount to add or substract
- a final letter ends and represents the amount in either days, weeks,
months or years (``d``, ``w``, ``m`` or ``y``)
Please note that this relative calculation makes the assumption of 30
days per month and 365 days per year.
"""
pattern_dq = '@([+|-]?)(\d+)([y|m|w|d])'
pattern_dq = '(?P<sign>[+|-]?)(?P<quantity>[0-9]+)(?P<timespan>[y|m|w|d])' # noqa: E501
match_dq = re.match(pattern_dq, string)
# test if the string matches the relative date pattern, add the parsed
# quantity to now in that case
if match_dq is not None:
sign = match_dq.group(1)
quantity = match_dq.group(2)
timespan = match_dq.group(3)
sign = match_dq.group('sign')
quantity = match_dq.group('quantity')
timespan = match_dq.group('timespan')
multiplier = -1 if sign == '-' else 1
days = cls.relative[timespan]
date = datetime.now() + multiplier * timedelta(

View file

@ -166,8 +166,7 @@ You can also use relative dates to the current time.
A relative date begins with an ``@``.
It looks like ``@-3w``, ``@2m`` or ``@-4d`` which means the date 3 weeks ago,
the date 2 months from now and the date 4 days ago.
A relative date consists of four parts:
- ``@`` indicates it's a date relative from now
A relative date consists of three parts:
- ``+`` or ``-`` sign is optional and defaults to ``+``. The ``+`` sign will
add a time quantity to the current date while the ``-`` sign will do the
opposite
@ -180,11 +179,11 @@ month and 365 days per year.
Here is an example that finds all the albums added between now and last week::
$ beet ls -a 'added:@-1w..'
$ beet ls -a 'added:-1w..'
Find all items added in a 2 weeks period 4 weeks ago::
Find all items added in a 2 weeks period 4 weeks ago::
$ beet ls -a 'added:@-6w..@-4w'
$ beet ls -a 'added:-6w..-4w'
Date *intervals*, like the numeric intervals described above, are separated by
two dots (``..``). You can specify a start, an end, or both.

View file

@ -47,8 +47,8 @@ class DateIntervalTest(unittest.TestCase):
self.assertContains('..2001', '2001-12-31T23:59:59')
self.assertExcludes('..2001', '2002-01-01T00:00:00')
self.assertContains('@-1d..@1d', _datepattern(datetime.now()))
self.assertExcludes('@-2d..@-1d', _datepattern(datetime.now()))
self.assertContains('-1d..1d', _datepattern(datetime.now()))
self.assertExcludes('-2d..-1d', _datepattern(datetime.now()))
def test_day_precision_intervals(self):
self.assertContains('2000-06-20..2000-06-20', '2000-06-20T00:00:00')
@ -168,37 +168,37 @@ class DateQueryTestRelativeMore(_common.LibTestCase):
def test_relative(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '@-4' + timespan + '..@+4' + timespan)
query = DateQuery('added', '-4' + timespan + '..+4' + timespan)
matched = self.lib.items(query)
self.assertEqual(len(matched), 1)
def test_relative_fail(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '@-2' + timespan + '..@-1' + timespan)
query = DateQuery('added', '-2' + timespan + '..-1' + timespan)
matched = self.lib.items(query)
self.assertEqual(len(matched), 0)
def test_start_relative(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '@-4' + timespan + '..')
query = DateQuery('added', '-4' + timespan + '..')
matched = self.lib.items(query)
self.assertEqual(len(matched), 1)
def test_start_relative_fail(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '@4' + timespan + '..')
query = DateQuery('added', '4' + timespan + '..')
matched = self.lib.items(query)
self.assertEqual(len(matched), 0)
def test_end_relative(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '..@+4' + timespan)
query = DateQuery('added', '..+4' + timespan)
matched = self.lib.items(query)
self.assertEqual(len(matched), 1)
def test_end_relative_fail(self):
for timespan in ['d', 'w', 'm', 'y']:
query = DateQuery('added', '..@-4' + timespan)
query = DateQuery('added', '..-4' + timespan)
matched = self.lib.items(query)
self.assertEqual(len(matched), 0)