--- a/mercurial/commands.py Tue Dec 05 21:35:44 2006 -0600
+++ b/mercurial/commands.py Wed Dec 06 13:27:39 2006 -0800
@@ -788,6 +788,12 @@
except KeyError:
raise util.Abort(_('invalid revision identifier %s') % rev)
+def debugdate(ui, date):
+ """parse and display a date"""
+ d = util.parsedate(date)
+ ui.write("internal: %s %s\n" % d)
+ ui.write("standard: %s\n" % util.datestr(d))
+
def debugindex(ui, file_):
"""dump the contents of an index file"""
r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "", 0)
@@ -2477,6 +2483,7 @@
"debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
"debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
"debugstate": (debugstate, [], _('debugstate')),
+ "debugdate": (debugdate, [], _('debugdata DATE')),
"debugdata": (debugdata, [], _('debugdata FILE REV')),
"debugindex": (debugindex, [], _('debugindex FILE')),
"debugindexdot": (debugindexdot, [], _('debugindexdot FILE')),
@@ -2727,7 +2734,7 @@
}
norepo = ("clone init version help debugancestor debugcomplete debugdata"
- " debugindex debugindexdot")
+ " debugindex debugindexdot debugdate")
optionalrepo = ("paths serve showconfig")
def findpossible(ui, cmd):
--- a/mercurial/help.py Tue Dec 05 21:35:44 2006 -0600
+++ b/mercurial/help.py Wed Dec 06 13:27:39 2006 -0800
@@ -9,37 +9,31 @@
"dates|Date Formats":
r'''
Some commands (backout, commit, tag) allow the user to specify a date.
- Possible formats for dates are:
-
-YYYY-mm-dd \HH:MM[:SS] [(+|-)NNNN]::
- This is a subset of ISO 8601, allowing just the recommended notations
- for date and time. The last part represents the timezone; if omitted,
- local time is assumed. Examples:
-
- "2005-08-22 03:27 -0700"
-
- "2006-04-19 21:39:51"
+ Many date formats are acceptible. Here are some examples:
-aaa bbb dd HH:MM:SS YYYY [(+|-)NNNN]::
- This is the date format used by the C library. Here, aaa stands for
- abbreviated weekday name and bbb for abbreviated month name. The last
- part represents the timezone; if omitted, local time is assumed.
- Examples:
+ "Wed Dec 6 13:18:29 2006" (local timezone assumed)
+ "Dec 6 13:18 -0600" (year assumed, time offset provided)
+ "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
+ "Dec 6" (midnight)
+ "13:18" (today assumed)
+ "3:39" (3:39AM assumed)
+ "3:39pm" (15:39)
+ "2006-12-6 13:18:29" (ISO 8601 format)
+ "2006-12-6 13:18"
+ "2006-12-6"
+ "12-6"
+ "12/6"
+ "12/6/6" (Dec 6 2006)
+ "" (Jan 1 00:00:00 1970 UTC)
- "Mon Aug 22 03:27:00 2005 -0700"
+ Lastly, there is Mercurial's internal format:
- "Wed Apr 19 21:39:51 2006"
+ "1165432709 0" (Wed Dec 6 13:18:29 2006 UTC)
-unixtime offset::
This is the internal representation format for dates. unixtime is
the number of seconds since the epoch (1970-01-01 00:00 UTC). offset
is the offset of the local timezone, in seconds west of UTC (negative
if the timezone is east of UTC).
- Examples:
-
- "1124706420 25200" (2005-08-22 03:27:00 -0700)
-
- "1145475591 -7200" (2006-04-19 21:39:51 +0200)
''',
'environment|env|Environment Variables':
--- a/mercurial/util.py Tue Dec 05 21:35:44 2006 -0600
+++ b/mercurial/util.py Wed Dec 06 13:27:39 2006 -0800
@@ -72,8 +72,29 @@
raise Abort("decoding near '%s': %s!\n" % (sub, inst))
# used by parsedate
-defaultdateformats = ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M',
- '%a %b %d %H:%M:%S %Y')
+defaultdateformats = (
+ '%Y-%m-%d %H:%M:%S',
+ '%Y-%m-%d %I:%M:%S%p',
+ '%Y-%m-%d %H:%M',
+ '%Y-%m-%d %I:%M%p',
+ '%Y-%m-%d',
+ '%m-%d',
+ '%m/%d',
+ '%m/%d/%y',
+ '%m/%d/%Y',
+ '%a %b %d %H:%M:%S %Y',
+ '%a %b %d %I:%M:%S%p %Y',
+ '%b %d %H:%M:%S %Y',
+ '%b %d %I:%M:%S%p',
+ '%b %d %H:%M',
+ '%b %d %I:%M%p',
+ '%b %d %Y',
+ '%b %d',
+ '%H:%M:%S',
+ '%I:%M:%SP',
+ '%H:%M',
+ '%I:%M%p',
+)
class SignalInterrupt(Exception):
"""Exception raised on SIGTERM and SIGHUP."""
@@ -1040,18 +1061,32 @@
def strdate(string, format='%a %b %d %H:%M:%S %Y'):
"""parse a localized time string and return a (unixtime, offset) tuple.
if the string cannot be parsed, ValueError is raised."""
- def hastimezone(string):
- return (string[-4:].isdigit() and
- (string[-5] == '+' or string[-5] == '-') and
- string[-6].isspace())
+ def timezone(string):
+ tz = string.split()[-1]
+ if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit():
+ tz = int(tz)
+ offset = - 3600 * (tz / 100) - 60 * (tz % 100)
+ return offset
+ if tz == "GMT" or tz == "UTC":
+ return 0
+ return None
# NOTE: unixtime = localunixtime + offset
- if hastimezone(string):
- date, tz = string[:-6], string[-5:]
- tz = int(tz)
- offset = - 3600 * (tz / 100) - 60 * (tz % 100)
- else:
- date, offset = string, None
+ offset, date = timezone(string), string
+ if offset != None:
+ date = " ".join(string.split()[:-1])
+
+ # add missing elements
+ if '%y' not in format.lower():
+ date += "@" + datestr(makedate(), "%Y", False)
+ format += "@%Y"
+ if '%m' not in format and '%b' not in format:
+ date += "@" + datestr(makedate(), "%m", False)
+ format += "@%m"
+ if '%d' not in format:
+ date += "@" + datestr(makedate(), "%d", False)
+ format += "@%d"
+
timetuple = time.strptime(date, format)
localunixtime = int(calendar.timegm(timetuple))
if offset is None:
@@ -1066,8 +1101,11 @@
"""parse a localized time string and return a (unixtime, offset) tuple.
The date may be a "unixtime offset" string or in one of the specified
formats."""
+ if not string:
+ return 0, 0
if not formats:
formats = defaultdateformats
+ string = string.strip()
try:
when, offset = map(int, string.split(' '))
except ValueError:
@@ -1079,17 +1117,15 @@
else:
break
else:
- raise ValueError(_('invalid date: %r '
- 'see hg(1) manual page for details')
- % string)
+ raise Abort(_('invalid date: %r ') % string)
# validate explicit (probably user-specified) date and
# time zone offset. values must fit in signed 32 bits for
# current 32-bit linux runtimes. timezones go from UTC-12
# to UTC+14
if abs(when) > 0x7fffffff:
- raise ValueError(_('date exceeds 32 bits: %d') % when)
+ raise Abort(_('date exceeds 32 bits: %d') % when)
if offset < -50400 or offset > 43200:
- raise ValueError(_('impossible time zone offset: %d') % offset)
+ raise Abort(_('impossible time zone offset: %d') % offset)
return when, offset
def shortuser(user):
--- a/tests/test-commit.out Tue Dec 05 21:35:44 2006 -0600
+++ b/tests/test-commit.out Wed Dec 06 13:27:39 2006 -0800
@@ -2,18 +2,13 @@
abort: impossible time zone offset: 4444444
transaction abort!
rollback completed
-abort: invalid date: '1\t15.1' see hg(1) manual page for details
-transaction abort!
-rollback completed
-abort: invalid date: 'foo bar' see hg(1) manual page for details
+abort: invalid date: '1\t15.1'
transaction abort!
rollback completed
-abort: invalid date: ' 1 4444' see hg(1) manual page for details
+abort: invalid date: 'foo bar'
transaction abort!
rollback completed
-abort: date exceeds 32 bits: 111111111111
-transaction abort!
-rollback completed
+nothing changed
% partial commit test
trouble committing bar!
abort: No such file or directory: .../test/bar
--- a/tests/test-debugcomplete.out Tue Dec 05 21:35:44 2006 -0600
+++ b/tests/test-debugcomplete.out Wed Dec 06 13:27:39 2006 -0800
@@ -61,6 +61,7 @@
debugcomplete
debugconfig
debugdata
+debugdate
debugindex
debugindexdot
debugrawcommit
--- a/tests/test-parse-date.out Tue Dec 05 21:35:44 2006 -0600
+++ b/tests/test-parse-date.out Wed Dec 06 13:27:39 2006 -0800
@@ -3,7 +3,7 @@
merging with changeset 2:e6c3abc120e7
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
-abort: invalid date: 'should fail' see hg(1) manual page for details
+abort: invalid date: 'should fail'
transaction abort!
rollback completed
abort: date exceeds 32 bits: 100000000000000000