Mercurial > hg
comparison mercurial/util.py @ 13212:5d0a30fad7de stable
date: fix matching of underspecified date ranges
(backport of 91bc001a592f to stable)
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 29 Dec 2010 14:19:31 -0600 |
parents | 5b83ab614dab |
children | 3eee7b42d17e e3bf16703e26 |
comparison
equal
deleted
inserted
replaced
13206:650314ed845d | 13212:5d0a30fad7de |
---|---|
1075 offset, date = timezone(string), string | 1075 offset, date = timezone(string), string |
1076 if offset != None: | 1076 if offset != None: |
1077 date = " ".join(string.split()[:-1]) | 1077 date = " ".join(string.split()[:-1]) |
1078 | 1078 |
1079 # add missing elements from defaults | 1079 # add missing elements from defaults |
1080 for part in defaults: | 1080 usenow = False # default to using biased defaults |
1081 for part in ("S", "M", "HI", "d", "mb", "yY"): # decreasing specificity | |
1081 found = [True for p in part if ("%"+p) in format] | 1082 found = [True for p in part if ("%"+p) in format] |
1082 if not found: | 1083 if not found: |
1083 date += "@" + defaults[part] | 1084 date += "@" + defaults[part][usenow] |
1084 format += "@%" + part[0] | 1085 format += "@%" + part[0] |
1086 else: | |
1087 # We've found a specific time element, less specific time | |
1088 # elements are relative to today | |
1089 usenow = True | |
1085 | 1090 |
1086 timetuple = time.strptime(date, format) | 1091 timetuple = time.strptime(date, format) |
1087 localunixtime = int(calendar.timegm(timetuple)) | 1092 localunixtime = int(calendar.timegm(timetuple)) |
1088 if offset is None: | 1093 if offset is None: |
1089 # local timezone | 1094 # local timezone |
1091 offset = unixtime - localunixtime | 1096 offset = unixtime - localunixtime |
1092 else: | 1097 else: |
1093 unixtime = localunixtime + offset | 1098 unixtime = localunixtime + offset |
1094 return unixtime, offset | 1099 return unixtime, offset |
1095 | 1100 |
1096 def parsedate(date, formats=None, defaults=None): | 1101 def parsedate(date, formats=None, bias={}): |
1097 """parse a localized date/time string and return a (unixtime, offset) tuple. | 1102 """parse a localized date/time and return a (unixtime, offset) tuple. |
1098 | 1103 |
1099 The date may be a "unixtime offset" string or in one of the specified | 1104 The date may be a "unixtime offset" string or in one of the specified |
1100 formats. If the date already is a (unixtime, offset) tuple, it is returned. | 1105 formats. If the date already is a (unixtime, offset) tuple, it is returned. |
1101 """ | 1106 """ |
1102 if not date: | 1107 if not date: |
1108 date = date.strip() | 1113 date = date.strip() |
1109 try: | 1114 try: |
1110 when, offset = map(int, date.split(' ')) | 1115 when, offset = map(int, date.split(' ')) |
1111 except ValueError: | 1116 except ValueError: |
1112 # fill out defaults | 1117 # fill out defaults |
1113 if not defaults: | |
1114 defaults = {} | |
1115 now = makedate() | 1118 now = makedate() |
1119 defaults = {} | |
1120 nowmap = {} | |
1116 for part in "d mb yY HI M S".split(): | 1121 for part in "d mb yY HI M S".split(): |
1117 if part not in defaults: | 1122 # this piece is for rounding the specific end of unknowns |
1123 b = bias.get(part) | |
1124 if b is None: | |
1118 if part[0] in "HMS": | 1125 if part[0] in "HMS": |
1119 defaults[part] = "00" | 1126 b = "00" |
1120 else: | 1127 else: |
1121 defaults[part] = datestr(now, "%" + part[0]) | 1128 b = "0" |
1129 | |
1130 # this piece is for matching the generic end to today's date | |
1131 n = datestr(now, "%" + part[0]) | |
1132 | |
1133 defaults[part] = (b, n) | |
1122 | 1134 |
1123 for format in formats: | 1135 for format in formats: |
1124 try: | 1136 try: |
1125 when, offset = strdate(date, format, defaults) | 1137 when, offset = strdate(date, format, defaults) |
1126 except (ValueError, OverflowError): | 1138 except (ValueError, OverflowError): |
1150 | 1162 |
1151 '<{date}' on or before a given date | 1163 '<{date}' on or before a given date |
1152 | 1164 |
1153 '>{date}' on or after a given date | 1165 '>{date}' on or after a given date |
1154 | 1166 |
1167 >>> p1 = parsedate("10:29:59") | |
1168 >>> p2 = parsedate("10:30:00") | |
1169 >>> p3 = parsedate("10:30:59") | |
1170 >>> p4 = parsedate("10:31:00") | |
1171 >>> p5 = parsedate("Sep 15 10:30:00 1999") | |
1172 >>> f = matchdate("10:30") | |
1173 >>> f(p1[0]) | |
1174 False | |
1175 >>> f(p2[0]) | |
1176 True | |
1177 >>> f(p3[0]) | |
1178 True | |
1179 >>> f(p4[0]) | |
1180 False | |
1181 >>> f(p5[0]) | |
1182 False | |
1155 """ | 1183 """ |
1156 | 1184 |
1157 def lower(date): | 1185 def lower(date): |
1158 d = dict(mb="1", d="1") | 1186 d = dict(mb="1", d="1") |
1159 return parsedate(date, extendeddateformats, d)[0] | 1187 return parsedate(date, extendeddateformats, d)[0] |