Mercurial > hg
changeset 13211:91bc001a592f
date: fix matching of underspecified date ranges
In a date like 10:30, there are two underspecified ends: the specific
end (seconds) and the broad end (day, month, year). When matching
"10:30", we need to allow the specific end to go from 0 to 59 seconds,
while the broad end is assumed to be today's date.
Similar handling applies for a date range like "Mar 1": year is fixed
to today, any time matches.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 29 Dec 2010 14:04:47 -0600 |
parents | 86a218df3c2b |
children | 3eee7b42d17e |
files | mercurial/util.py tests/test-doctest.py |
diffstat | 2 files changed, 40 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/util.py Wed Dec 29 11:18:27 2010 -0600 +++ b/mercurial/util.py Wed Dec 29 14:04:47 2010 -0600 @@ -1079,11 +1079,16 @@ date = " ".join(string.split()[:-1]) # add missing elements from defaults - for part in defaults: + usenow = False # default to using biased defaults + for part in ("S", "M", "HI", "d", "mb", "yY"): # decreasing specificity found = [True for p in part if ("%"+p) in format] if not found: - date += "@" + defaults[part] + date += "@" + defaults[part][usenow] format += "@%" + part[0] + else: + # We've found a specific time element, less specific time + # elements are relative to today + usenow = True timetuple = time.strptime(date, format) localunixtime = int(calendar.timegm(timetuple)) @@ -1095,8 +1100,8 @@ unixtime = localunixtime + offset return unixtime, offset -def parsedate(date, formats=None, defaults=None): - """parse a localized date/time string and return a (unixtime, offset) tuple. +def parsedate(date, formats=None, bias={}): + """parse a localized date/time and return a (unixtime, offset) tuple. The date may be a "unixtime offset" string or in one of the specified formats. If the date already is a (unixtime, offset) tuple, it is returned. @@ -1112,15 +1117,22 @@ when, offset = map(int, date.split(' ')) except ValueError: # fill out defaults - if not defaults: - defaults = {} now = makedate() + defaults = {} + nowmap = {} for part in ("d", "mb", "yY", "HI", "M", "S"): - if part not in defaults: + # this piece is for rounding the specific end of unknowns + b = bias.get(part) + if b is None: if part[0] in "HMS": - defaults[part] = "00" + b = "00" else: - defaults[part] = datestr(now, "%" + part[0]) + b = "0" + + # this piece is for matching the generic end to today's date + n = datestr(now, "%" + part[0]) + + defaults[part] = (b, n) for format in formats: try: @@ -1154,6 +1166,22 @@ '>{date}' on or after a given date + >>> p1 = parsedate("10:29:59") + >>> p2 = parsedate("10:30:00") + >>> p3 = parsedate("10:30:59") + >>> p4 = parsedate("10:31:00") + >>> p5 = parsedate("Sep 15 10:30:00 1999") + >>> f = matchdate("10:30") + >>> f(p1[0]) + False + >>> f(p2[0]) + True + >>> f(p3[0]) + True + >>> f(p4[0]) + False + >>> f(p5[0]) + False """ def lower(date):
--- a/tests/test-doctest.py Wed Dec 29 11:18:27 2010 -0600 +++ b/tests/test-doctest.py Wed Dec 29 14:04:47 2010 -0600 @@ -16,6 +16,9 @@ import mercurial.url doctest.testmod(mercurial.url) +import mercurial.util +doctest.testmod(mercurial.util) + import mercurial.encoding doctest.testmod(mercurial.encoding)