# HG changeset patch # User Florent Gallaire # Date 1460117463 -7200 # Node ID 87c6ad2251d8703d7f16d51e99e3d1c040f0be49 # Parent 9d31582dd6360e05caa32998da2b0cc89dd621ef date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513) DVCS are very useful to store various texts (as legislation) written before Unix epoch. Fri, 13 Dec 1901 is a nice gain over Thu, 01 Jan 1970. Revert dd24f3e7ca9e and e1002cf9fe54, fix c208dcd0f709. Add tests. diff -r 9d31582dd636 -r 87c6ad2251d8 mercurial/util.py --- a/mercurial/util.py Wed Apr 06 19:08:04 2016 +0000 +++ b/mercurial/util.py Fri Apr 08 14:11:03 2016 +0200 @@ -1585,9 +1585,6 @@ number of seconds away from UTC. if timezone is false, do not append time zone to string.""" t, tz = date or makedate() - if t < 0: - t = 0 # time.gmtime(lt) fails on Windows for lt < -43200 - tz = 0 if "%1" in format or "%2" in format or "%z" in format: sign = (tz > 0) and "-" or "+" minutes = abs(tz) // 60 @@ -1595,12 +1592,16 @@ format = format.replace("%z", "%1%2") format = format.replace("%1", "%c%02d" % (sign, q)) format = format.replace("%2", "%02d" % r) - try: - t = time.gmtime(float(t) - tz) - except ValueError: - # time was out of range - t = time.gmtime(sys.maxint) - s = time.strftime(format, t) + d = t - tz + if d > 0x7fffffff: + d = 0x7fffffff + elif d < -0x7fffffff: + d = -0x7fffffff + # Never use time.gmtime() and datetime.datetime.fromtimestamp() + # because they use the gmtime() system call which is buggy on Windows + # for negative values. + t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d) + s = t.strftime(format) return s def shortdate(date=None): @@ -1721,8 +1722,6 @@ # to UTC+14 if abs(when) > 0x7fffffff: raise Abort(_('date exceeds 32 bits: %d') % when) - if when < 0: - raise Abort(_('negative date value: %d') % when) if offset < -50400 or offset > 43200: raise Abort(_('impossible time zone offset: %d') % offset) return when, offset diff -r 9d31582dd636 -r 87c6ad2251d8 tests/test-commit.t --- a/tests/test-commit.t Wed Apr 06 19:08:04 2016 +0000 +++ b/tests/test-commit.t Fri Apr 08 14:11:03 2016 +0200 @@ -27,8 +27,21 @@ $ hg commit -d '111111111111 0' -m commit-7 abort: date exceeds 32 bits: 111111111111 [255] - $ hg commit -d '-7654321 3600' -m commit-7 - abort: negative date value: -7654321 + $ hg commit -d '-111111111111 0' -m commit-7 + abort: date exceeds 32 bits: -111111111111 + [255] + $ echo foo >> foo + $ hg commit -d '1901-12-13 20:45:53 +0000' -m commit-7-2 + $ echo foo >> foo + $ hg commit -d '-2147483647 0' -m commit-7-3 + $ hg log -T '{rev} {date|isodatesec}\n' -l2 + 3 1901-12-13 20:45:53 +0000 + 2 1901-12-13 20:45:53 +0000 + $ hg commit -d '1901-12-13 20:45:52 +0000' -m commit-7 + abort: date exceeds 32 bits: -2147483648 + [255] + $ hg commit -d '-2147483648 0' -m commit-7 + abort: date exceeds 32 bits: -2147483648 [255] commit added file that has been deleted @@ -54,7 +67,7 @@ dir/file committing manifest committing changelog - committed changeset 2:d2a76177cb42 + committed changeset 4:76aab26859d7 $ echo > dir.file $ hg add @@ -78,7 +91,7 @@ dir/file committing manifest committing changelog - committed changeset 3:1cd62a2d8db5 + committed changeset 5:9a50557f1baf $ cd .. $ hg commit -m commit-14 does-not-exist @@ -102,7 +115,7 @@ dir/file committing manifest committing changelog - committed changeset 4:49176991390e + committed changeset 6:4b4c75bf422d An empty date was interpreted as epoch origin