Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Doc/library/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,6 @@ Other constructors, all class methods:

.. versionadded:: 3.7


.. classmethod:: datetime.fromisocalendar(year, week, day)

Return a :class:`datetime` corresponding to the ISO calendar date specified
Expand All @@ -871,15 +870,20 @@ Other constructors, all class methods:

.. versionadded:: 3.8

.. classmethod:: datetime.strptime(date_string, format)
.. classmethod:: datetime.strptime(date_string, format, infos=None)

Return a :class:`.datetime` corresponding to *date_string*, parsed according to
*format*. This is equivalent to ``datetime(*(time.strptime(date_string,
format)[0:6]))``. :exc:`ValueError` is raised if the date_string and format
can't be parsed by :func:`time.strptime` or if it returns a value which isn't a
time tuple. For a complete list of formatting directives, see
:ref:`strftime-strptime-behavior`.
To interpret a timezone name (`%Z`), provide a converter with the *infos*
argument that accepts a tz naive :class:`datetime` object and the tz
name string. It should return a :class:`tzinfo` object.

.. versionchanged:: 3.9
Added the *infos* argument.


Class attributes:
Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Changes in the Python API
-------------------------

* :meth:`datetime.strptime` now accepts an optional 3rd parameter
`infos`. It accepts a callable or mapping that converts a timezone name to a
tzinfo object. For example ``datetime.strptime("2018-01-05 13:10:00 CET",
"%Y-%m-%d %H:%M:%S %Z", lambda dt, tzname: ...)``. It is used to interpret
the timezone name given by `%Z`.
16 changes: 14 additions & 2 deletions Lib/_strptime.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"):
tt = _strptime(data_string, format)[0]
return time.struct_time(tt[:time._STRUCT_TM_ITEMS])

def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"):
def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y", infos=None):
"""Return a class cls instance based on the input string and the
format string."""
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
Expand All @@ -576,4 +576,16 @@ def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"):
tz = datetime_timezone(tzdelta)
args += (tz,)

return cls(*args)
dt = cls(*args)

if gmtoff is None and tzname is not None and infos:
try:
tz = infos[tzname]
except KeyError:
tz = None
except TypeError:
tz = infos(dt, tzname)
if tz:
dt = dt.replace(tzinfo=tz)

return dt
4 changes: 2 additions & 2 deletions Lib/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -1939,10 +1939,10 @@ def __str__(self):
return self.isoformat(sep=' ')

@classmethod
def strptime(cls, date_string, format):
def strptime(cls, date_string, format, tzinfos=None):
'string, format -> new datetime parsed from a string (like time.strptime()).'
import _strptime
return _strptime._strptime_datetime(cls, date_string, format)
return _strptime._strptime_datetime(cls, date_string, format, tzinfos)

def utcoffset(self):
"""Return the timezone offset as timedelta positive east of UTC (negative west of
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1862,3 +1862,4 @@ Diego Rojas
Edison Abahurire
Geoff Shannon
Batuhan Taskaya
Arjan Keeman