mercurial/utils/dateutil.py
changeset 51284 f15cb5111a1e
parent 51282 9d3721552b6c
child 51739 55677d115045
equal deleted inserted replaced
51283:81224afd938d 51284:f15cb5111a1e
    79     b"%b",
    79     b"%b",
    80     b"%b %Y",
    80     b"%b %Y",
    81 )
    81 )
    82 
    82 
    83 
    83 
    84 def makedate(timestamp=None):
    84 def makedate(timestamp: Optional[float] = None) -> hgdate:
    85     # type: (Optional[float]) -> hgdate
       
    86     """Return a unix timestamp (or the current time) as a (unixtime,
    85     """Return a unix timestamp (or the current time) as a (unixtime,
    87     offset) tuple based off the local timezone."""
    86     offset) tuple based off the local timezone."""
    88     if timestamp is None:
    87     if timestamp is None:
    89         timestamp = time.time()
    88         timestamp = time.time()
    90     if timestamp < 0:
    89     if timestamp < 0:
   101         .timestamp()
   100         .timestamp()
   102     )
   101     )
   103     return timestamp, tz
   102     return timestamp, tz
   104 
   103 
   105 
   104 
   106 def datestr(date=None, format=b'%a %b %d %H:%M:%S %Y %1%2'):
   105 def datestr(
   107     # type: (Optional[hgdate], bytes) -> bytes
   106     date: Optional[hgdate] = None,
       
   107     format: bytes = b'%a %b %d %H:%M:%S %Y %1%2',
       
   108 ) -> bytes:
   108     """represent a (unixtime, offset) tuple as a localized time.
   109     """represent a (unixtime, offset) tuple as a localized time.
   109     unixtime is seconds since the epoch, and offset is the time zone's
   110     unixtime is seconds since the epoch, and offset is the time zone's
   110     number of seconds away from UTC.
   111     number of seconds away from UTC.
   111 
   112 
   112     >>> datestr((0, 0))
   113     >>> datestr((0, 0))
   139     t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d)
   140     t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d)
   140     s = encoding.strtolocal(t.strftime(encoding.strfromlocal(format)))
   141     s = encoding.strtolocal(t.strftime(encoding.strfromlocal(format)))
   141     return s
   142     return s
   142 
   143 
   143 
   144 
   144 def shortdate(date=None):
   145 def shortdate(date: Optional[hgdate] = None) -> bytes:
   145     # type: (Optional[hgdate]) -> bytes
       
   146     """turn (timestamp, tzoff) tuple into iso 8631 date."""
   146     """turn (timestamp, tzoff) tuple into iso 8631 date."""
   147     return datestr(date, format=b'%Y-%m-%d')
   147     return datestr(date, format=b'%Y-%m-%d')
   148 
   148 
   149 
   149 
   150 def parsetimezone(s):
   150 def parsetimezone(s: bytes) -> Tuple[Optional[int], bytes]:
   151     # type: (bytes) -> Tuple[Optional[int], bytes]
       
   152     """find a trailing timezone, if any, in string, and return a
   151     """find a trailing timezone, if any, in string, and return a
   153     (offset, remainder) pair"""
   152     (offset, remainder) pair"""
   154     s = pycompat.bytestr(s)
   153     s = pycompat.bytestr(s)
   155 
   154 
   156     if s.endswith(b"GMT") or s.endswith(b"UTC"):
   155     if s.endswith(b"GMT") or s.endswith(b"UTC"):
   181         return -sign * (hours * 60 + minutes) * 60, s[:-6]
   180         return -sign * (hours * 60 + minutes) * 60, s[:-6]
   182 
   181 
   183     return None, s
   182     return None, s
   184 
   183 
   185 
   184 
   186 def strdate(string, format, defaults=None):
   185 def strdate(
   187     # type: (bytes, bytes, Optional[Dict[bytes, Tuple[bytes, bytes]]]) -> hgdate
   186     string: bytes,
       
   187     format: bytes,
       
   188     defaults: Optional[Dict[bytes, Tuple[bytes, bytes]]] = None,
       
   189 ) -> hgdate:
   188     """parse a localized time string and return a (unixtime, offset) tuple.
   190     """parse a localized time string and return a (unixtime, offset) tuple.
   189     if the string cannot be parsed, ValueError is raised."""
   191     if the string cannot be parsed, ValueError is raised."""
   190     if defaults is None:
   192     if defaults is None:
   191         defaults = {}
   193         defaults = {}
   192 
   194 
   224     else:
   226     else:
   225         unixtime = localunixtime + offset
   227         unixtime = localunixtime + offset
   226     return unixtime, offset
   228     return unixtime, offset
   227 
   229 
   228 
   230 
   229 def parsedate(date, formats=None, bias=None):
   231 def parsedate(
   230     # type: (Union[bytes, hgdate], Optional[Iterable[bytes]], Optional[Dict[bytes, bytes]]) -> hgdate
   232     date: Union[bytes, hgdate],
       
   233     formats: Optional[Iterable[bytes]] = None,
       
   234     bias: Optional[Dict[bytes, bytes]] = None,
       
   235 ) -> hgdate:
   231     """parse a localized date/time and return a (unixtime, offset) tuple.
   236     """parse a localized date/time and return a (unixtime, offset) tuple.
   232 
   237 
   233     The date may be a "unixtime offset" string or in one of the specified
   238     The date may be a "unixtime offset" string or in one of the specified
   234     formats. If the date already is a (unixtime, offset) tuple, it is returned.
   239     formats. If the date already is a (unixtime, offset) tuple, it is returned.
   235 
   240 
   314     if offset < -50400 or offset > 43200:
   319     if offset < -50400 or offset > 43200:
   315         raise error.ParseError(_(b'impossible time zone offset: %d') % offset)
   320         raise error.ParseError(_(b'impossible time zone offset: %d') % offset)
   316     return when, offset
   321     return when, offset
   317 
   322 
   318 
   323 
   319 def matchdate(date):
   324 def matchdate(date: bytes) -> Callable[[float], bool]:
   320     # type: (bytes) -> Callable[[float], bool]
       
   321     """Return a function that matches a given date match specifier
   325     """Return a function that matches a given date match specifier
   322 
   326 
   323     Formats include:
   327     Formats include:
   324 
   328 
   325     '{date}' match a given date to the accuracy provided
   329     '{date}' match a given date to the accuracy provided
   344     False
   348     False
   345     >>> f(p5[0])
   349     >>> f(p5[0])
   346     False
   350     False
   347     """
   351     """
   348 
   352 
   349     def lower(date):
   353     def lower(date: bytes) -> float:
   350         # type: (bytes) -> float
       
   351         d = {b'mb': b"1", b'd': b"1"}
   354         d = {b'mb': b"1", b'd': b"1"}
   352         return parsedate(date, extendeddateformats, d)[0]
   355         return parsedate(date, extendeddateformats, d)[0]
   353 
   356 
   354     def upper(date):
   357     def upper(date: bytes) -> float:
   355         # type: (bytes) -> float
       
   356         d = {b'mb': b"12", b'HI': b"23", b'M': b"59", b'S': b"59"}
   358         d = {b'mb': b"12", b'HI': b"23", b'M': b"59", b'S': b"59"}
   357         for days in (b"31", b"30", b"29"):
   359         for days in (b"31", b"30", b"29"):
   358             try:
   360             try:
   359                 d[b"d"] = days
   361                 d[b"d"] = days
   360                 return parsedate(date, extendeddateformats, d)[0]
   362                 return parsedate(date, extendeddateformats, d)[0]