Extract strdate from util.py to utils/dateutil.py
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
- Lint Skipped 
- Unit
- Unit Tests Skipped 
| lothiraldan | 
| hg-reviewers | 
Extract strdate from util.py to utils/dateutil.py
| Lint Skipped | 
| Unit Tests Skipped | 
| Path | Packages | |||
|---|---|---|---|---|
| M | hgext/convert/darcs.py (3 lines) | |||
| M | hgext/convert/monotone.py (3 lines) | |||
| M | mercurial/util.py (42 lines) | |||
| M | mercurial/utils/dateutil.py (35 lines) | 
| Status | Author | Revision | |
|---|---|---|---|
| Abandoned | lothiraldan | ||
| Abandoned | durin42 | D2056 util: extract matchdate  | |
| Abandoned | durin42 | D2055 util: extract parsedate  | |
| Abandoned | durin42 | D2054 util: extract strdate  | |
| Abandoned | durin42 | ||
| Abandoned | durin42 | D2052 util: extract shortdate  | |
| Abandoned | durin42 | D2051 util: extract datestr  | |
| Abandoned | durin42 | D2050 util: extract makedate  | |
| Abandoned | durin42 | ||
| Abandoned | lothiraldan | ||
| Abandoned | durin42 | 
| man.append(path) | man.append(path) | ||||
| return man | return man | ||||
| def getheads(self): | def getheads(self): | ||||
| return self.parents[None] | return self.parents[None] | ||||
| def getcommit(self, rev): | def getcommit(self, rev): | ||||
| elt = self.changes[rev] | elt = self.changes[rev] | ||||
| date = util.strdate(elt.get('local_date'), '%a %b %d %H:%M:%S %Z %Y') | dateformat = '%a %b %d %H:%M:%S %Z %Y' | ||||
| date = dateutil.strdate(elt.get('local_date'), dateformat) | |||||
| desc = elt.findtext('name') + '\n' + elt.findtext('comment', '') | desc = elt.findtext('name') + '\n' + elt.findtext('comment', '') | ||||
| # etree can return unicode objects for name, comment, and author, | # etree can return unicode objects for name, comment, and author, | ||||
| # so recode() is used to ensure str objects are emitted. | # so recode() is used to ensure str objects are emitted. | ||||
| newdateformat = '%Y-%m-%d %H:%M:%S %1%2' | newdateformat = '%Y-%m-%d %H:%M:%S %1%2' | ||||
| return common.commit(author=self.recode(elt.get('author')), | return common.commit(author=self.recode(elt.get('author')), | ||||
| date=dateutil.datestr(date, newdateformat), | date=dateutil.datestr(date, newdateformat), | ||||
| desc=self.recode(desc).strip(), | desc=self.recode(desc).strip(), | ||||
| parents=self.parents[rev]) | parents=self.parents[rev]) | ||||
| # monotone.py - monotone support for the convert extension | # monotone.py - monotone support for the convert extension | ||||
| # | # | ||||
| # Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and | # Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and | ||||
| # others | # others | ||||
| # | # | ||||
| # This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
| # GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
| from __future__ import absolute_import | from __future__ import absolute_import | ||||
| import os | import os | ||||
| import re | import re | ||||
| from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
| from mercurial import ( | from mercurial import ( | ||||
| error, | error, | ||||
| util, | |||||
| ) | ) | ||||
| from mercurial.utils import dateutil | from mercurial.utils import dateutil | ||||
| from . import common | from . import common | ||||
| class monotone_source(common.converter_source, common.commandline): | class monotone_source(common.converter_source, common.commandline): | ||||
| def __init__(self, ui, repotype, path=None, revs=None): | def __init__(self, ui, repotype, path=None, revs=None): | ||||
| common.converter_source.__init__(self, ui, repotype, path, revs) | common.converter_source.__init__(self, ui, repotype, path, revs) | ||||
| def getcommit(self, rev): | def getcommit(self, rev): | ||||
| extra = {} | extra = {} | ||||
| certs = self.mtngetcerts(rev) | certs = self.mtngetcerts(rev) | ||||
| if certs.get('suspend') == certs["branch"]: | if certs.get('suspend') == certs["branch"]: | ||||
| extra['close'] = 1 | extra['close'] = 1 | ||||
| dateformat = "%Y-%m-%dT%H:%M:%S" | dateformat = "%Y-%m-%dT%H:%M:%S" | ||||
| return common.commit( | return common.commit( | ||||
| author=certs["author"], | author=certs["author"], | ||||
| date=dateutil.datestr(util.strdate(certs["date"], dateformat)), | date=dateutil.datestr(dateutil.strdate(certs["date"], dateformat)), | ||||
| desc=certs["changelog"], | desc=certs["changelog"], | ||||
| rev=rev, | rev=rev, | ||||
| parents=self.mtnrun("parents", rev).splitlines(), | parents=self.mtnrun("parents", rev).splitlines(), | ||||
| branch=certs["branch"], | branch=certs["branch"], | ||||
| extra=extra) | extra=extra) | ||||
| def gettags(self): | def gettags(self): | ||||
| tags = {} | tags = {} | ||||
| This contains helper routines that are independent of the SCM core and | This contains helper routines that are independent of the SCM core and | ||||
| hide platform-specific details from the core. | hide platform-specific details from the core. | ||||
| """ | """ | ||||
| from __future__ import absolute_import, print_function | from __future__ import absolute_import, print_function | ||||
| import abc | import abc | ||||
| import bz2 | import bz2 | ||||
| import calendar | |||||
| import codecs | import codecs | ||||
| import collections | import collections | ||||
| import contextlib | import contextlib | ||||
| import datetime | import datetime | ||||
| import errno | import errno | ||||
| import gc | import gc | ||||
| import hashlib | import hashlib | ||||
| import imp | import imp | ||||
| nbytes = min(limit, size) | nbytes = min(limit, size) | ||||
| s = nbytes and f.read(nbytes) | s = nbytes and f.read(nbytes) | ||||
| if not s: | if not s: | ||||
| break | break | ||||
| if limit: | if limit: | ||||
| limit -= len(s) | limit -= len(s) | ||||
| yield s | yield s | ||||
| def strdate(string, format, defaults=None): | |||||
| """parse a localized time string and return a (unixtime, offset) tuple. | |||||
| if the string cannot be parsed, ValueError is raised.""" | |||||
| if defaults is None: | |||||
| defaults = {} | |||||
| # NOTE: unixtime = localunixtime + offset | |||||
| offset, date = dateutil.parsetimezone(string) | |||||
| # add missing elements from defaults | |||||
| usenow = False # default to using biased defaults | |||||
| for part in ("S", "M", "HI", "d", "mb", "yY"): # decreasing specificity | |||||
| part = pycompat.bytestr(part) | |||||
| found = [True for p in part if ("%"+p) in format] | |||||
| if not found: | |||||
| date += "@" + defaults[part][usenow] | |||||
| format += "@%" + part[0] | |||||
| else: | |||||
| # We've found a specific time element, less specific time | |||||
| # elements are relative to today | |||||
| usenow = True | |||||
| timetuple = time.strptime(encoding.strfromlocal(date), | |||||
| encoding.strfromlocal(format)) | |||||
| localunixtime = int(calendar.timegm(timetuple)) | |||||
| if offset is None: | |||||
| # local timezone | |||||
| unixtime = int(time.mktime(timetuple)) | |||||
| offset = unixtime - localunixtime | |||||
| else: | |||||
| unixtime = localunixtime + offset | |||||
| return unixtime, offset | |||||
| def parsedate(date, formats=None, bias=None): | def parsedate(date, formats=None, bias=None): | ||||
| """parse a localized date/time and return a (unixtime, offset) tuple. | """parse a localized date/time and return a (unixtime, offset) tuple. | ||||
| The date may be a "unixtime offset" string or in one of the specified | The date may be a "unixtime offset" string or in one of the specified | ||||
| formats. If the date already is a (unixtime, offset) tuple, it is returned. | formats. If the date already is a (unixtime, offset) tuple, it is returned. | ||||
| >>> parsedate(b' today ') == parsedate( | >>> parsedate(b' today ') == parsedate( | ||||
| ... datetime.date.today().strftime('%b %d').encode('ascii')) | ... datetime.date.today().strftime('%b %d').encode('ascii')) | ||||
| # this piece is for matching the generic end to today's date | # this piece is for matching the generic end to today's date | ||||
| n = dateutil.datestr(now, "%" + part[0:1]) | n = dateutil.datestr(now, "%" + part[0:1]) | ||||
| defaults[part] = (b, n) | defaults[part] = (b, n) | ||||
| for format in formats: | for format in formats: | ||||
| try: | try: | ||||
| when, offset = strdate(date, format, defaults) | when, offset = dateutil.strdate(date, format, defaults) | ||||
| except (ValueError, OverflowError): | except (ValueError, OverflowError): | ||||
| pass | pass | ||||
| else: | else: | ||||
| break | break | ||||
| else: | else: | ||||
| raise error.ParseError(_('invalid date: %r') % date) | raise error.ParseError(_('invalid date: %r') % date) | ||||
| # validate explicit (probably user-specified) date and | # validate explicit (probably user-specified) date and | ||||
| # time zone offset. values must fit in signed 32 bits for | # time zone offset. values must fit in signed 32 bits for | ||||
| return dateutil.shortdate(*args, **kwargs) | return dateutil.shortdate(*args, **kwargs) | ||||
| def parsetimezone(*args, **kwargs): | def parsetimezone(*args, **kwargs): | ||||
| msg = ("'util.parsetimezone' is deprecated, " | msg = ("'util.parsetimezone' is deprecated, " | ||||
| "use 'utils.dateutil.parsetimezone'") | "use 'utils.dateutil.parsetimezone'") | ||||
| nouideprecwarn(msg, "4.6") | nouideprecwarn(msg, "4.6") | ||||
| return dateutil.parsetimezone(*args, **kwargs) | return dateutil.parsetimezone(*args, **kwargs) | ||||
| def strdate(*args, **kwargs): | |||||
| msg = ("'util.strdate' is deprecated, " | |||||
| "use 'utils.dateutil.strdate'") | |||||
| nouideprecwarn(msg, "4.6") | |||||
| return dateutil.strdate(*args, **kwargs) | |||||
| # util.py - Mercurial utility functions relative to dates | # util.py - Mercurial utility functions relative to dates | ||||
| # | # | ||||
| # Copyright 2018 Boris Feld <boris.feld@octobus.net> | # Copyright 2018 Boris Feld <boris.feld@octobus.net> | ||||
| # | # | ||||
| # This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
| # GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
| from __future__ import absolute_import, print_function | from __future__ import absolute_import, print_function | ||||
| import calendar | |||||
| import datetime | import datetime | ||||
| import time | import time | ||||
| from ..i18n import _ | from ..i18n import _ | ||||
| from .. import ( | from .. import ( | ||||
| encoding, | encoding, | ||||
| error, | error, | ||||
| pycompat, | |||||
| ) | ) | ||||
| # used by parsedate | # used by parsedate | ||||
| defaultdateformats = ( | defaultdateformats = ( | ||||
| '%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 | '%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 | ||||
| '%Y-%m-%dT%H:%M', # without seconds | '%Y-%m-%dT%H:%M', # without seconds | ||||
| '%Y-%m-%dT%H%M%S', # another awful but legal variant without : | '%Y-%m-%dT%H%M%S', # another awful but legal variant without : | ||||
| '%Y-%m-%dT%H%M', # without seconds | '%Y-%m-%dT%H%M', # without seconds | ||||
| s[-5:-3].isdigit() and s[-2:].isdigit()): | s[-5:-3].isdigit() and s[-2:].isdigit()): | ||||
| sign = (s[-6] == "+") and 1 or -1 | sign = (s[-6] == "+") and 1 or -1 | ||||
| hours = int(s[-5:-3]) | hours = int(s[-5:-3]) | ||||
| minutes = int(s[-2:]) | minutes = int(s[-2:]) | ||||
| return -sign * (hours * 60 + minutes) * 60, s[:-6] | return -sign * (hours * 60 + minutes) * 60, s[:-6] | ||||
| return None, s | return None, s | ||||
| def strdate(string, format, defaults=None): | |||||
| """parse a localized time string and return a (unixtime, offset) tuple. | |||||
| if the string cannot be parsed, ValueError is raised.""" | |||||
| if defaults is None: | |||||
| defaults = {} | |||||
| # NOTE: unixtime = localunixtime + offset | |||||
| offset, date = parsetimezone(string) | |||||
| # add missing elements from defaults | |||||
| usenow = False # default to using biased defaults | |||||
| for part in ("S", "M", "HI", "d", "mb", "yY"): # decreasing specificity | |||||
| part = pycompat.bytestr(part) | |||||
| found = [True for p in part if ("%"+p) in format] | |||||
| if not found: | |||||
| date += "@" + defaults[part][usenow] | |||||
| format += "@%" + part[0] | |||||
| else: | |||||
| # We've found a specific time element, less specific time | |||||
| # elements are relative to today | |||||
| usenow = True | |||||
| timetuple = time.strptime(encoding.strfromlocal(date), | |||||
| encoding.strfromlocal(format)) | |||||
| localunixtime = int(calendar.timegm(timetuple)) | |||||
| if offset is None: | |||||
| # local timezone | |||||
| unixtime = int(time.mktime(timetuple)) | |||||
| offset = unixtime - localunixtime | |||||
| else: | |||||
| unixtime = localunixtime + offset | |||||
| return unixtime, offset | |||||