Patchwork D2051: util: extract datestr

login
register
mail settings
Submitter phabricator
Date Feb. 5, 2018, 4:25 p.m.
Message ID <differential-rev-PHID-DREV-ijwsnjpvdji2jsded2sb-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/27330/
State New
Headers show

Comments

phabricator - Feb. 5, 2018, 4:25 p.m.
lothiraldan created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Extract datestr from util.py to utils/dateutil.py

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2051

AFFECTED FILES
  hgext/blackbox.py
  hgext/convert/cvs.py
  hgext/convert/cvsps.py
  hgext/convert/darcs.py
  hgext/convert/gnuarch.py
  hgext/convert/hg.py
  hgext/convert/monotone.py
  hgext/convert/p4.py
  hgext/convert/subversion.py
  hgext/keyword.py
  hgext/notify.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/debugcommands.py
  mercurial/formatter.py
  mercurial/mdiff.py
  mercurial/obsutil.py
  mercurial/patch.py
  mercurial/subrepo.py
  mercurial/templatefilters.py
  mercurial/templater.py
  mercurial/util.py
  mercurial/utils/dateutil.py

CHANGE DETAILS




To: lothiraldan, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/utils/dateutil.py b/mercurial/utils/dateutil.py
--- a/mercurial/utils/dateutil.py
+++ b/mercurial/utils/dateutil.py
@@ -12,6 +12,7 @@ 
 
 from ..i18n import _
 from .. import (
+    encoding,
     error,
 )
 
@@ -70,3 +71,38 @@ 
     tz = delta.days * 86400 + delta.seconds
     return timestamp, tz
 
+def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'):
+    """represent a (unixtime, offset) tuple as a localized time.
+    unixtime is seconds since the epoch, and offset is the time zone's
+    number of seconds away from UTC.
+
+    >>> datestr((0, 0))
+    'Thu Jan 01 00:00:00 1970 +0000'
+    >>> datestr((42, 0))
+    'Thu Jan 01 00:00:42 1970 +0000'
+    >>> datestr((-42, 0))
+    'Wed Dec 31 23:59:18 1969 +0000'
+    >>> datestr((0x7fffffff, 0))
+    'Tue Jan 19 03:14:07 2038 +0000'
+    >>> datestr((-0x80000000, 0))
+    'Fri Dec 13 20:45:52 1901 +0000'
+    """
+    t, tz = date or makedate()
+    if "%1" in format or "%2" in format or "%z" in format:
+        sign = (tz > 0) and "-" or "+"
+        minutes = abs(tz) // 60
+        q, r = divmod(minutes, 60)
+        format = format.replace("%z", "%1%2")
+        format = format.replace("%1", "%c%02d" % (sign, q))
+        format = format.replace("%2", "%02d" % r)
+    d = t - tz
+    if d > 0x7fffffff:
+        d = 0x7fffffff
+    elif d < -0x80000000:
+        d = -0x80000000
+    # 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 = encoding.strtolocal(t.strftime(encoding.strfromlocal(format)))
+    return s
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1906,45 +1906,9 @@ 
             limit -= len(s)
         yield s
 
-def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'):
-    """represent a (unixtime, offset) tuple as a localized time.
-    unixtime is seconds since the epoch, and offset is the time zone's
-    number of seconds away from UTC.
-
-    >>> datestr((0, 0))
-    'Thu Jan 01 00:00:00 1970 +0000'
-    >>> datestr((42, 0))
-    'Thu Jan 01 00:00:42 1970 +0000'
-    >>> datestr((-42, 0))
-    'Wed Dec 31 23:59:18 1969 +0000'
-    >>> datestr((0x7fffffff, 0))
-    'Tue Jan 19 03:14:07 2038 +0000'
-    >>> datestr((-0x80000000, 0))
-    'Fri Dec 13 20:45:52 1901 +0000'
-    """
-    t, tz = date or dateutil.makedate()
-    if "%1" in format or "%2" in format or "%z" in format:
-        sign = (tz > 0) and "-" or "+"
-        minutes = abs(tz) // 60
-        q, r = divmod(minutes, 60)
-        format = format.replace("%z", "%1%2")
-        format = format.replace("%1", "%c%02d" % (sign, q))
-        format = format.replace("%2", "%02d" % r)
-    d = t - tz
-    if d > 0x7fffffff:
-        d = 0x7fffffff
-    elif d < -0x80000000:
-        d = -0x80000000
-    # 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 = encoding.strtolocal(t.strftime(encoding.strfromlocal(format)))
-    return s
-
 def shortdate(date=None):
     """turn (timestamp, tzoff) tuple into iso 8631 date."""
-    return datestr(date, format='%Y-%m-%d')
+    return dateutil.datestr(date, format='%Y-%m-%d')
 
 def parsetimezone(s):
     """find a trailing timezone, if any, in string, and return a
@@ -2063,7 +2027,7 @@ 
                     b = "0"
 
             # this piece is for matching the generic end to today's date
-            n = datestr(now, "%" + part[0:1])
+            n = dateutil.datestr(now, "%" + part[0:1])
 
             defaults[part] = (b, n)
 
@@ -3905,3 +3869,9 @@ 
     nouideprecwarn(msg, "4.6")
     return dateutil.makedate(*args, **kwargs)
 
+def datestr(*args, **kwargs):
+    msg = ("'util.datestr' is deprecated, "
+           "use 'utils.dateutil.datestr'")
+    nouideprecwarn(msg, "4.6")
+    return dateutil.datestr(*args, **kwargs)
+
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -593,9 +593,9 @@ 
         fmt = evalstring(context, mapping, args[1])
     try:
         if fmt is None:
-            return util.datestr(date)
+            return dateutil.datestr(date)
         else:
-            return util.datestr(date, fmt)
+            return dateutil.datestr(date, fmt)
     except (TypeError, ValueError):
         # i18n: "date" is a keyword
         raise error.ParseError(_("date expects a date information"))
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -22,6 +22,7 @@ 
     url,
     util,
 )
+from .utils import dateutil
 
 urlerr = util.urlerr
 urlreq = util.urlreq
@@ -196,15 +197,15 @@ 
     """Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
     +0200".
     """
-    return util.datestr(text, '%Y-%m-%d %H:%M %1%2')
+    return dateutil.datestr(text, '%Y-%m-%d %H:%M %1%2')
 
 @templatefilter('isodatesec')
 def isodatesec(text):
     """Date. Returns the date in ISO 8601 format, including
     seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
     filter.
     """
-    return util.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
+    return dateutil.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
 
 def indent(text, prefix):
     '''indent each non-empty line of text after first with prefix.'''
@@ -318,14 +319,14 @@ 
     """Date. Returns a date using the Internet date format
     specified in RFC 3339: "2009-08-18T13:00:13+02:00".
     """
-    return util.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
+    return dateutil.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
 
 @templatefilter('rfc822date')
 def rfc822date(text):
     """Date. Returns a date using the same format used in email
     headers: "Tue, 18 Aug 2009 13:00:13 +0200".
     """
-    return util.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
+    return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
 
 @templatefilter('short')
 def short(text):
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -37,6 +37,7 @@ 
     util,
     vfs as vfsmod,
 )
+from .utils import dateutil
 
 hg = None
 propertycache = util.propertycache
@@ -1829,7 +1830,7 @@ 
         if date:
             # git's date parser silently ignores when seconds < 1e9
             # convert to ISO8601
-            env['GIT_AUTHOR_DATE'] = util.datestr(date,
+            env['GIT_AUTHOR_DATE'] = dateutil.datestr(date,
                                                   '%Y-%m-%dT%H:%M:%S %1%2')
         self._gitcommand(cmd, env=env)
         # make sure commit works otherwise HEAD might not exist under certain
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -41,6 +41,7 @@ 
     util,
     vfs as vfsmod,
 )
+from .utils import dateutil
 
 diffhelpers = policy.importmod(r'diffhelpers')
 stringio = util.stringio
@@ -2670,8 +2671,8 @@ 
     def isempty(fctx):
         return fctx is None or fctx.size() == 0
 
-    date1 = util.datestr(ctx1.date())
-    date2 = util.datestr(ctx2.date())
+    date1 = dateutil.datestr(ctx1.date())
+    date2 = dateutil.datestr(ctx2.date())
 
     gitmode = {'l': '120000', 'x': '100755', '': '100644'}
 
diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -15,6 +15,7 @@ 
     phases,
     util,
 )
+from .utils import dateutil
 
 class marker(object):
     """Wrap obsolete marker raw data"""
@@ -856,11 +857,11 @@ 
         max_date = max(dates)
 
         if min_date == max_date:
-            fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
+            fmtmin_date = dateutil.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
             line.append(" (at %s)" % fmtmin_date)
         else:
-            fmtmin_date = util.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
-            fmtmax_date = util.datestr(max_date, '%Y-%m-%d %H:%M %1%2')
+            fmtmin_date = dateutil.datestr(min_date, '%Y-%m-%d %H:%M %1%2')
+            fmtmax_date = dateutil.datestr(max_date, '%Y-%m-%d %H:%M %1%2')
             line.append(" (between %s and %s)" % (fmtmin_date, fmtmax_date))
 
     return "".join(line)
diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -18,6 +18,7 @@ 
     pycompat,
     util,
 )
+from .utils import dateutil
 
 bdiff = policy.importmod(r'bdiff')
 mpatch = policy.importmod(r'mpatch')
@@ -259,7 +260,7 @@ 
         aprefix = 'a/'
         bprefix = 'b/'
 
-    epoch = util.datestr((0, 0))
+    epoch = dateutil.datestr((0, 0))
 
     fn1 = util.pconvert(fn1)
     fn2 = util.pconvert(fn2)
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -126,6 +126,7 @@ 
     templater,
     util,
 )
+from .utils import dateutil
 
 pickle = util.pickle
 
@@ -243,7 +244,7 @@ 
     @staticmethod
     def formatdate(date, fmt):
         '''stringify date tuple in the given format'''
-        return util.datestr(date, fmt)
+        return dateutil.datestr(date, fmt)
     @staticmethod
     def formatdict(data, key, value, fmt, sep):
         '''stringify key-value pairs separated by sep'''
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -73,6 +73,7 @@ 
     util,
     vfs as vfsmod,
 )
+from .utils import dateutil
 
 release = lockmod.release
 
@@ -560,7 +561,7 @@ 
     else:
         d = util.parsedate(date)
     ui.write(("internal: %s %s\n") % d)
-    ui.write(("standard: %s\n") % util.datestr(d))
+    ui.write(("standard: %s\n") % dateutil.datestr(d))
     if range:
         m = util.matchdate(range)
         ui.write(("match: %s\n") % m(d[0]))
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -304,7 +304,7 @@ 
     if ui.quiet:
         datefunc = util.shortdate
     else:
-        datefunc = util.datestr
+        datefunc = dateutil.datestr
     if ctx.rev() is None:
         def hexfn(node):
             if node is None:
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -50,6 +50,7 @@ 
     util,
     vfs as vfsmod,
 )
+from .utils import dateutil
 stringio = util.stringio
 
 # templates of common command options
@@ -1506,7 +1507,7 @@ 
     write("# HG changeset patch\n")
     write("# User %s\n" % ctx.user())
     write("# Date %d %d\n" % ctx.date())
-    write("#      %s\n" % util.datestr(ctx.date()))
+    write("#      %s\n" % dateutil.datestr(ctx.date()))
     if branch and branch != 'default':
         write("# Branch %s\n" % branch)
     write("# Node ID %s\n" % hex(node))
@@ -1738,7 +1739,7 @@ 
                           % scmutil.formatrevnode(self.ui, mrev, mnode),
                           label='ui.debug log.manifest')
         self.ui.write(columns['user'] % ctx.user(), label='log.user')
-        self.ui.write(columns['date'] % util.datestr(ctx.date()),
+        self.ui.write(columns['date'] % dateutil.datestr(ctx.date()),
                       label='log.date')
 
         if ctx.isunstable():
@@ -2114,7 +2115,7 @@ 
         rev = ctx.rev()
         if rev in results:
             ui.status(_("found revision %s from %s\n") %
-                      (rev, util.datestr(results[rev])))
+                      (rev, dateutil.datestr(results[rev])))
             return '%d' % rev
 
     raise error.Abort(_("revision matching date not found"))
diff --git a/hgext/notify.py b/hgext/notify.py
--- a/hgext/notify.py
+++ b/hgext/notify.py
@@ -149,6 +149,7 @@ 
     registrar,
     util,
 )
+from mercurial.utils import dateutil
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -361,7 +362,7 @@ 
             for k, v in headers:
                 msg[k] = v
 
-        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
+        msg['Date'] = dateutil.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
 
         # try to make subject line exist and be useful
         if not subject:
diff --git a/hgext/keyword.py b/hgext/keyword.py
--- a/hgext/keyword.py
+++ b/hgext/keyword.py
@@ -110,6 +110,7 @@ 
     templatefilters,
     util,
 )
+from mercurial.utils import dateutil
 
 cmdtable = {}
 command = registrar.command(cmdtable)
@@ -155,21 +156,21 @@ 
 def utcdate(text):
     '''Date. Returns a UTC-date in this format: "2009/08/18 11:00:13".
     '''
-    return util.datestr((util.parsedate(text)[0], 0), '%Y/%m/%d %H:%M:%S')
+    return dateutil.datestr((util.parsedate(text)[0], 0), '%Y/%m/%d %H:%M:%S')
 # date like in svn's $Date
 @templatefilter('svnisodate')
 def svnisodate(text):
     '''Date. Returns a date in this format: "2009-08-18 13:00:13
     +0200 (Tue, 18 Aug 2009)".
     '''
-    return util.datestr(text, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
+    return dateutil.datestr(text, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
 # date like in svn's $Id
 @templatefilter('svnutcdate')
 def svnutcdate(text):
     '''Date. Returns a UTC-date in this format: "2009-08-18
     11:00:13Z".
     '''
-    return util.datestr((util.parsedate(text)[0], 0), '%Y-%m-%d %H:%M:%SZ')
+    return dateutil.datestr((util.parsedate(text)[0], 0), '%Y-%m-%d %H:%M:%SZ')
 
 # make keyword tools accessible
 kwtools = {'hgcmd': ''}
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -16,6 +16,7 @@ 
     util,
     vfs as vfsmod,
 )
+from mercurial.utils import dateutil
 
 from . import common
 
@@ -912,7 +913,7 @@ 
                 branch = None
 
             cset = commit(author=author,
-                          date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
+                          date=dateutil.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
                           desc=log,
                           parents=parents,
                           branch=branch,
diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py
--- a/hgext/convert/p4.py
+++ b/hgext/convert/p4.py
@@ -14,6 +14,7 @@ 
     error,
     util,
 )
+from mercurial.utils import dateutil
 
 from . import common
 
@@ -346,7 +347,7 @@ 
             parents = []
 
         return common.commit(author=self.recode(obj["user"]),
-            date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
+            date=dateutil.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
             parents=parents, desc=desc, branch=None, rev=obj['change'],
             extra={"p4": obj['change'], "convert_revision": obj['change']})
 
diff --git a/hgext/convert/monotone.py b/hgext/convert/monotone.py
--- a/hgext/convert/monotone.py
+++ b/hgext/convert/monotone.py
@@ -15,6 +15,7 @@ 
     error,
     util,
 )
+from mercurial.utils import dateutil
 
 from . import common
 
@@ -308,9 +309,10 @@ 
         certs = self.mtngetcerts(rev)
         if certs.get('suspend') == certs["branch"]:
             extra['close'] = 1
+        dateformat = "%Y-%m-%dT%H:%M:%S"
         return common.commit(
             author=certs["author"],
-            date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
+            date=dateutil.datestr(util.strdate(certs["date"], dateformat)),
             desc=certs["changelog"],
             rev=rev,
             parents=self.mtnrun("parents", rev).splitlines(),
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -36,6 +36,7 @@ 
     scmutil,
     util,
 )
+from mercurial.utils import dateutil
 stringio = util.stringio
 
 from . import common
@@ -588,7 +589,7 @@ 
         crev = rev
 
         return common.commit(author=ctx.user(),
-                             date=util.datestr(ctx.date(),
+                             date=dateutil.datestr(ctx.date(),
                                                '%Y-%m-%d %H:%M:%S %1%2'),
                              desc=ctx.description(),
                              rev=crev,
diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py
--- a/hgext/convert/gnuarch.py
+++ b/hgext/convert/gnuarch.py
@@ -19,6 +19,7 @@ 
     error,
     util,
 )
+from mercurial.utils import dateutil
 from . import common
 
 class gnuarch_source(common.converter_source, common.commandline):
@@ -280,8 +281,8 @@ 
             catlog = self.catlogparser.parsestr(data)
 
             # Commit date
-            self.changes[rev].date = util.datestr(
-                util.strdate(catlog['Standard-date'],
+            self.changes[rev].date = dateutil.datestr(
+                dateutil.strdate(catlog['Standard-date'],
                              '%Y-%m-%d %H:%M:%S'))
 
             # Commit author
diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py
--- a/hgext/convert/darcs.py
+++ b/hgext/convert/darcs.py
@@ -16,6 +16,7 @@ 
     error,
     util,
 )
+from mercurial.utils import dateutil
 from . import common
 NoRepo = common.NoRepo
 
@@ -152,8 +153,9 @@ 
         desc = elt.findtext('name') + '\n' + elt.findtext('comment', '')
         # etree can return unicode objects for name, comment, and author,
         # so recode() is used to ensure str objects are emitted.
+        newdateformat = '%Y-%m-%d %H:%M:%S %1%2'
         return common.commit(author=self.recode(elt.get('author')),
-                             date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
+                             date=dateutil.datestr(date, newdateformat),
                              desc=self.recode(desc).strip(),
                              parents=self.parents[rev])
 
diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py
--- a/hgext/convert/cvsps.py
+++ b/hgext/convert/cvsps.py
@@ -17,6 +17,7 @@ 
     pycompat,
     util,
 )
+from mercurial.utils import dateutil
 
 pickle = util.pickle
 
@@ -192,7 +193,7 @@ 
 
         if oldlog:
             date = oldlog[-1].date    # last commit date as a (time,tz) tuple
-            date = util.datestr(date, '%Y/%m/%d %H:%M:%S %1%2')
+            date = dateutil.datestr(date, '%Y/%m/%d %H:%M:%S %1%2')
 
     # build the CVS commandline
     cmd = ['cvs', '-q']
@@ -900,7 +901,7 @@ 
             #       bug-for-bug compatibility with cvsps.
             ui.write('---------------------\n')
             ui.write(('PatchSet %d \n' % cs.id))
-            ui.write(('Date: %s\n' % util.datestr(cs.date,
+            ui.write(('Date: %s\n' % dateutil.datestr(cs.date,
                                                  '%Y/%m/%d %H:%M:%S %1%2')))
             ui.write(('Author: %s\n' % cs.author))
             ui.write(('Branch: %s\n' % (cs.branch or 'HEAD')))
diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py
--- a/hgext/convert/cvs.py
+++ b/hgext/convert/cvs.py
@@ -18,6 +18,7 @@ 
     pycompat,
     util,
 )
+from mercurial.utils import dateutil
 
 from . import (
     common,
@@ -93,7 +94,7 @@ 
                 cs.comment = self.recode(cs.comment)
                 if self.ui.configbool('convert', 'localtimezone'):
                     cs.date = makedatetimestamp(cs.date[0])
-                date = util.datestr(cs.date, '%Y-%m-%d %H:%M:%S %1%2')
+                date = dateutil.datestr(cs.date, '%Y-%m-%d %H:%M:%S %1%2')
                 self.tags.update(dict.fromkeys(cs.tags, id))
 
                 files = {}
diff --git a/hgext/blackbox.py b/hgext/blackbox.py
--- a/hgext/blackbox.py
+++ b/hgext/blackbox.py
@@ -49,6 +49,7 @@ 
     ui as uimod,
     util,
 )
+from mercurial.utils import dateutil
 
 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -164,7 +165,7 @@ 
                 return
             ui._bbinlog = True
             default = self.configdate('devel', 'default-date')
-            date = util.datestr(default, '%Y/%m/%d %H:%M:%S')
+            date = dateutil.datestr(default, '%Y/%m/%d %H:%M:%S')
             user = util.getuser()
             pid = '%d' % util.getpid()
             formattedmsg = msg[0] % msg[1:]