D2051: util: extract datestr
lothiraldan (Boris Feld)
phabricator at mercurial-scm.org
Mon Feb 5 16:25:29 UTC 2018
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
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:]
To: lothiraldan, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list