mirror of https://github.com/python/cpython.git
Closes #27595: Document PEP 495 (Local Time Disambiguation) features.
This commit is contained in:
parent
208536132b
commit
53868aaabb
|
@ -1,46 +1,13 @@
|
|||
from datetime import tzinfo, timedelta, datetime
|
||||
from datetime import tzinfo, timedelta, datetime, timezone
|
||||
|
||||
ZERO = timedelta(0)
|
||||
HOUR = timedelta(hours=1)
|
||||
|
||||
# A UTC class.
|
||||
|
||||
class UTC(tzinfo):
|
||||
"""UTC"""
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return ZERO
|
||||
|
||||
def tzname(self, dt):
|
||||
return "UTC"
|
||||
|
||||
def dst(self, dt):
|
||||
return ZERO
|
||||
|
||||
utc = UTC()
|
||||
|
||||
# A class building tzinfo objects for fixed-offset time zones.
|
||||
# Note that FixedOffset(0, "UTC") is a different way to build a
|
||||
# UTC tzinfo object.
|
||||
|
||||
class FixedOffset(tzinfo):
|
||||
"""Fixed offset in minutes east from UTC."""
|
||||
|
||||
def __init__(self, offset, name):
|
||||
self.__offset = timedelta(minutes=offset)
|
||||
self.__name = name
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return self.__offset
|
||||
|
||||
def tzname(self, dt):
|
||||
return self.__name
|
||||
|
||||
def dst(self, dt):
|
||||
return ZERO
|
||||
SECOND = timedelta(seconds=1)
|
||||
|
||||
# A class capturing the platform's idea of local time.
|
||||
|
||||
# (May result in wrong values on historical times in
|
||||
# timezones where UTC offset and/or the DST rules had
|
||||
# changed in the past.)
|
||||
import time as _time
|
||||
|
||||
STDOFFSET = timedelta(seconds = -_time.timezone)
|
||||
|
@ -53,6 +20,16 @@ def dst(self, dt):
|
|||
|
||||
class LocalTimezone(tzinfo):
|
||||
|
||||
def fromutc(self, dt):
|
||||
assert dt.tzinfo is self
|
||||
stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND
|
||||
args = _time.localtime(stamp)[:6]
|
||||
dst_diff = DSTDIFF // SECOND
|
||||
# Detect fold
|
||||
fold = (args == _time.localtime(stamp - dst_diff))
|
||||
return datetime(*args, microsecond=dt.microsecond,
|
||||
tzinfo=self, fold=fold)
|
||||
|
||||
def utcoffset(self, dt):
|
||||
if self._isdst(dt):
|
||||
return DSTOFFSET
|
||||
|
@ -99,20 +76,37 @@ def first_sunday_on_or_after(dt):
|
|||
# In the US, since 2007, DST starts at 2am (standard time) on the second
|
||||
# Sunday in March, which is the first Sunday on or after Mar 8.
|
||||
DSTSTART_2007 = datetime(1, 3, 8, 2)
|
||||
# and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
|
||||
DSTEND_2007 = datetime(1, 11, 1, 1)
|
||||
# and ends at 2am (DST time) on the first Sunday of Nov.
|
||||
DSTEND_2007 = datetime(1, 11, 1, 2)
|
||||
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
|
||||
# Sunday in April and to end at 2am (DST time; 1am standard time) on the last
|
||||
# Sunday in April and to end at 2am (DST time) on the last
|
||||
# Sunday of October, which is the first Sunday on or after Oct 25.
|
||||
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
|
||||
DSTEND_1987_2006 = datetime(1, 10, 25, 1)
|
||||
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
|
||||
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
|
||||
# Sunday in April (the one on or after April 24) and to end at 2am (DST time;
|
||||
# 1am standard time) on the last Sunday of October, which is the first Sunday
|
||||
# Sunday in April (the one on or after April 24) and to end at 2am (DST time)
|
||||
# on the last Sunday of October, which is the first Sunday
|
||||
# on or after Oct 25.
|
||||
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
|
||||
DSTEND_1967_1986 = DSTEND_1987_2006
|
||||
|
||||
def us_dst_range(year):
|
||||
# Find start and end times for US DST. For years before 1967, return
|
||||
# start = end for no DST.
|
||||
if 2006 < year:
|
||||
dststart, dstend = DSTSTART_2007, DSTEND_2007
|
||||
elif 1986 < year < 2007:
|
||||
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
|
||||
elif 1966 < year < 1987:
|
||||
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
|
||||
else:
|
||||
return (datetime(year, 1, 1), ) * 2
|
||||
|
||||
start = first_sunday_on_or_after(dststart.replace(year=year))
|
||||
end = first_sunday_on_or_after(dstend.replace(year=year))
|
||||
return start, end
|
||||
|
||||
|
||||
class USTimeZone(tzinfo):
|
||||
|
||||
def __init__(self, hours, reprname, stdname, dstname):
|
||||
|
@ -141,27 +135,39 @@ def dst(self, dt):
|
|||
# implementation) passes a datetime with dt.tzinfo is self.
|
||||
return ZERO
|
||||
assert dt.tzinfo is self
|
||||
|
||||
# Find start and end times for US DST. For years before 1967, return
|
||||
# ZERO for no DST.
|
||||
if 2006 < dt.year:
|
||||
dststart, dstend = DSTSTART_2007, DSTEND_2007
|
||||
elif 1986 < dt.year < 2007:
|
||||
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
|
||||
elif 1966 < dt.year < 1987:
|
||||
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
|
||||
else:
|
||||
return ZERO
|
||||
|
||||
start = first_sunday_on_or_after(dststart.replace(year=dt.year))
|
||||
end = first_sunday_on_or_after(dstend.replace(year=dt.year))
|
||||
|
||||
start, end = us_dst_range(dt.year)
|
||||
# Can't compare naive to aware objects, so strip the timezone from
|
||||
# dt first.
|
||||
if start <= dt.replace(tzinfo=None) < end:
|
||||
dt = dt.replace(tzinfo=None)
|
||||
if start + HOUR <= dt < end - HOUR:
|
||||
# DST is in effect.
|
||||
return HOUR
|
||||
else:
|
||||
return ZERO
|
||||
if end - HOUR <= dt < end:
|
||||
# Fold (an ambiguous hour): use dt.fold to disambiguate.
|
||||
return ZERO if dt.fold else HOUR
|
||||
if start <= dt < start + HOUR:
|
||||
# Gap (a non-existent hour): reverse the fold rule.
|
||||
return HOUR if dt.fold else ZERO
|
||||
# DST is off.
|
||||
return ZERO
|
||||
|
||||
def fromutc(self, dt):
|
||||
assert dt.tzinfo is self
|
||||
start, end = us_dst_range(dt.year)
|
||||
start = start.replace(tzinfo=self)
|
||||
end = end.replace(tzinfo=self)
|
||||
std_time = dt + self.stdoffset
|
||||
dst_time = std_time + HOUR
|
||||
if end <= dst_time < end + HOUR:
|
||||
# Repeated hour
|
||||
return std_time.replace(fold=1)
|
||||
if std_time < start or dst_time >= end:
|
||||
# Standard time
|
||||
return std_time
|
||||
if start <= std_time < end - HOUR:
|
||||
# Daylight saving time
|
||||
return dst_time
|
||||
|
||||
|
||||
Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
|
||||
Central = USTimeZone(-6, "Central", "CST", "CDT")
|
||||
|
|
|
@ -522,7 +522,7 @@ objects are considered to be true.
|
|||
|
||||
Instance methods:
|
||||
|
||||
.. method:: date.replace(year, month, day)
|
||||
.. method:: date.replace(year=self.year, month=self.month, day=self.day)
|
||||
|
||||
Return a date with the same value, except for those parameters given new
|
||||
values by whichever keyword arguments are specified. For example, if ``d ==
|
||||
|
@ -683,22 +683,26 @@ both directions; like a time object, :class:`.datetime` assumes there are exactl
|
|||
|
||||
Constructor:
|
||||
|
||||
.. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
|
||||
.. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
|
||||
|
||||
The year, month and day arguments are required. *tzinfo* may be ``None``, or an
|
||||
instance of a :class:`tzinfo` subclass. The remaining arguments may be integers,
|
||||
in the following ranges:
|
||||
|
||||
* ``MINYEAR <= year <= MAXYEAR``
|
||||
* ``1 <= month <= 12``
|
||||
* ``1 <= day <= number of days in the given month and year``
|
||||
* ``0 <= hour < 24``
|
||||
* ``0 <= minute < 60``
|
||||
* ``0 <= second < 60``
|
||||
* ``0 <= microsecond < 1000000``
|
||||
* ``MINYEAR <= year <= MAXYEAR``,
|
||||
* ``1 <= month <= 12``,
|
||||
* ``1 <= day <= number of days in the given month and year``,
|
||||
* ``0 <= hour < 24``,
|
||||
* ``0 <= minute < 60``,
|
||||
* ``0 <= second < 60``,
|
||||
* ``0 <= microsecond < 1000000``,
|
||||
* ``fold in [0, 1]``.
|
||||
|
||||
If an argument outside those ranges is given, :exc:`ValueError` is raised.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
Added the ``fold`` argument.
|
||||
|
||||
Other constructors, all class methods:
|
||||
|
||||
.. classmethod:: datetime.today()
|
||||
|
@ -758,6 +762,8 @@ Other constructors, all class methods:
|
|||
instead of :exc:`ValueError` on :c:func:`localtime` or :c:func:`gmtime`
|
||||
failure.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
:meth:`fromtimestamp` may return instances with :attr:`.fold` set to 1.
|
||||
|
||||
.. classmethod:: datetime.utcfromtimestamp(timestamp)
|
||||
|
||||
|
@ -794,7 +800,7 @@ Other constructors, all class methods:
|
|||
microsecond of the result are all 0, and :attr:`.tzinfo` is ``None``.
|
||||
|
||||
|
||||
.. classmethod:: datetime.combine(date, time[, tzinfo])
|
||||
.. classmethod:: datetime.combine(date, time, tzinfo=self.tzinfo)
|
||||
|
||||
Return a new :class:`.datetime` object whose date components are equal to the
|
||||
given :class:`date` object's, and whose time components
|
||||
|
@ -886,6 +892,16 @@ Instance attributes (read-only):
|
|||
or ``None`` if none was passed.
|
||||
|
||||
|
||||
.. attribute:: datetime.fold
|
||||
|
||||
In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A
|
||||
repeated interval occurs when clocks are rolled back at the end of daylight saving
|
||||
time or when the UTC offset for the current zone is decreased for political reasons.)
|
||||
The value 0 (1) represents the earlier (later) of the two moments with the same wall
|
||||
time representation.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
Supported operations:
|
||||
|
||||
+---------------------------------------+--------------------------------+
|
||||
|
@ -974,23 +990,34 @@ Instance methods:
|
|||
|
||||
.. method:: datetime.time()
|
||||
|
||||
Return :class:`.time` object with same hour, minute, second and microsecond.
|
||||
Return :class:`.time` object with same hour, minute, second, microsecond and fold.
|
||||
:attr:`.tzinfo` is ``None``. See also method :meth:`timetz`.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
The fold value is copied to the returned :class:`.time` object.
|
||||
|
||||
|
||||
.. method:: datetime.timetz()
|
||||
|
||||
Return :class:`.time` object with same hour, minute, second, microsecond, and
|
||||
Return :class:`.time` object with same hour, minute, second, microsecond, fold, and
|
||||
tzinfo attributes. See also method :meth:`time`.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
The fold value is copied to the returned :class:`.time` object.
|
||||
|
||||
.. method:: datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
|
||||
|
||||
.. method:: datetime.replace(year=self.year, month=self.month, day=self.day, \
|
||||
hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, \
|
||||
tzinfo=self.tzinfo, * fold=0)
|
||||
|
||||
Return a datetime with the same attributes, except for those attributes given
|
||||
new values by whichever keyword arguments are specified. Note that
|
||||
``tzinfo=None`` can be specified to create a naive datetime from an aware
|
||||
datetime with no conversion of date and time data.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
Added the ``fold`` argument.
|
||||
|
||||
|
||||
.. method:: datetime.astimezone(tz=None)
|
||||
|
||||
|
@ -999,23 +1026,20 @@ Instance methods:
|
|||
*self*, but in *tz*'s local time.
|
||||
|
||||
If provided, *tz* must be an instance of a :class:`tzinfo` subclass, and its
|
||||
:meth:`utcoffset` and :meth:`dst` methods must not return ``None``. *self* must
|
||||
be aware (``self.tzinfo`` must not be ``None``, and ``self.utcoffset()`` must
|
||||
not return ``None``).
|
||||
:meth:`utcoffset` and :meth:`dst` methods must not return ``None``. If *self*
|
||||
is naive (``self.tzinfo is None``), it is presumed to represent time in the
|
||||
system timezone.
|
||||
|
||||
If called without arguments (or with ``tz=None``) the system local
|
||||
timezone is assumed. The ``.tzinfo`` attribute of the converted
|
||||
timezone is assumed for the target timezone. The ``.tzinfo`` attribute of the converted
|
||||
datetime instance will be set to an instance of :class:`timezone`
|
||||
with the zone name and offset obtained from the OS.
|
||||
|
||||
If ``self.tzinfo`` is *tz*, ``self.astimezone(tz)`` is equal to *self*: no
|
||||
adjustment of date or time data is performed. Else the result is local
|
||||
time in time zone *tz*, representing the same UTC time as *self*: after
|
||||
``astz = dt.astimezone(tz)``, ``astz - astz.utcoffset()`` will usually have
|
||||
the same date and time data as ``dt - dt.utcoffset()``. The discussion
|
||||
of class :class:`tzinfo` explains the cases at Daylight Saving Time transition
|
||||
boundaries where this cannot be achieved (an issue only if *tz* models both
|
||||
standard and daylight time).
|
||||
time in the timezone *tz*, representing the same UTC time as *self*: after
|
||||
``astz = dt.astimezone(tz)``, ``astz - astz.utcoffset()`` will have
|
||||
the same date and time data as ``dt - dt.utcoffset()``.
|
||||
|
||||
If you merely want to attach a time zone object *tz* to a datetime *dt* without
|
||||
adjustment of date and time data, use ``dt.replace(tzinfo=tz)``. If you
|
||||
|
@ -1037,6 +1061,10 @@ Instance methods:
|
|||
.. versionchanged:: 3.3
|
||||
*tz* now can be omitted.
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
The :meth:`astimezone` method can now be called on naive instances that
|
||||
are presumed to represent system local time.
|
||||
|
||||
|
||||
.. method:: datetime.utcoffset()
|
||||
|
||||
|
@ -1113,6 +1141,10 @@ Instance methods:
|
|||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
.. versionchanged:: 3.6
|
||||
The :meth:`timestamp` method uses the :attr:`.fold` attribute to
|
||||
disambiguate the times during a repeated interval.
|
||||
|
||||
.. note::
|
||||
|
||||
There is no method to obtain the POSIX timestamp directly from a
|
||||
|
@ -1342,16 +1374,17 @@ Using datetime with tzinfo:
|
|||
A time object represents a (local) time of day, independent of any particular
|
||||
day, and subject to adjustment via a :class:`tzinfo` object.
|
||||
|
||||
.. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
|
||||
.. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
|
||||
|
||||
All arguments are optional. *tzinfo* may be ``None``, or an instance of a
|
||||
:class:`tzinfo` subclass. The remaining arguments may be integers, in the
|
||||
following ranges:
|
||||
|
||||
* ``0 <= hour < 24``
|
||||
* ``0 <= minute < 60``
|
||||
* ``0 <= second < 60``
|
||||
* ``0 <= microsecond < 1000000``.
|
||||
* ``0 <= hour < 24``,
|
||||
* ``0 <= minute < 60``,
|
||||
* ``0 <= second < 60``,
|
||||
* ``0 <= microsecond < 1000000``,
|
||||
* ``fold in [0, 1]``.
|
||||
|
||||
If an argument outside those ranges is given, :exc:`ValueError` is raised. All
|
||||
default to ``0`` except *tzinfo*, which defaults to :const:`None`.
|
||||
|
@ -1404,6 +1437,17 @@ Instance attributes (read-only):
|
|||
``None`` if none was passed.
|
||||
|
||||
|
||||
.. attribute:: time.fold
|
||||
|
||||
In ``[0, 1]``. Used to disambiguate wall times during a repeated interval. (A
|
||||
repeated interval occurs when clocks are rolled back at the end of daylight saving
|
||||
time or when the UTC offset for the current zone is decreased for political reasons.)
|
||||
The value 0 (1) represents the earlier (later) of the two moments with the same wall
|
||||
time representation.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
Supported operations:
|
||||
|
||||
* comparison of :class:`.time` to :class:`.time`, where *a* is considered less
|
||||
|
@ -1439,13 +1483,17 @@ In boolean contexts, a :class:`.time` object is always considered to be true.
|
|||
|
||||
Instance methods:
|
||||
|
||||
.. method:: time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])
|
||||
.. method:: time.replace(hour=self.hour, minute=self.minute, second=self.second, \
|
||||
microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
|
||||
|
||||
Return a :class:`.time` with the same value, except for those attributes given
|
||||
new values by whichever keyword arguments are specified. Note that
|
||||
``tzinfo=None`` can be specified to create a naive :class:`.time` from an
|
||||
aware :class:`.time`, without conversion of the time data.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
Added the ``fold`` argument.
|
||||
|
||||
|
||||
.. method:: time.isoformat(timespec='auto')
|
||||
|
||||
|
@ -1754,9 +1802,19 @@ minute after 1:59 (EST) on the second Sunday in March, and ends the minute after
|
|||
When DST starts (the "start" line), the local wall clock leaps from 1:59 to
|
||||
3:00. A wall time of the form 2:MM doesn't really make sense on that day, so
|
||||
``astimezone(Eastern)`` won't deliver a result with ``hour == 2`` on the day DST
|
||||
begins. In order for :meth:`astimezone` to make this guarantee, the
|
||||
:meth:`tzinfo.dst` method must consider times in the "missing hour" (2:MM for
|
||||
Eastern) to be in daylight time.
|
||||
begins. For example, at the Spring forward transition of 2016, we get
|
||||
|
||||
>>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc)
|
||||
>>> for i in range(4):
|
||||
... u = u0 + i*HOUR
|
||||
... t = u.astimezone(Eastern)
|
||||
... print(u.time(), 'UTC =', t.time(), t.tzname())
|
||||
...
|
||||
05:00:00 UTC = 00:00:00 EST
|
||||
06:00:00 UTC = 01:00:00 EST
|
||||
07:00:00 UTC = 03:00:00 EDT
|
||||
08:00:00 UTC = 04:00:00 EDT
|
||||
|
||||
|
||||
When DST ends (the "end" line), there's a potentially worse problem: there's an
|
||||
hour that can't be spelled unambiguously in local wall time: the last hour of
|
||||
|
@ -1765,28 +1823,41 @@ daylight time ends. The local wall clock leaps from 1:59 (daylight time) back
|
|||
to 1:00 (standard time) again. Local times of the form 1:MM are ambiguous.
|
||||
:meth:`astimezone` mimics the local clock's behavior by mapping two adjacent UTC
|
||||
hours into the same local hour then. In the Eastern example, UTC times of the
|
||||
form 5:MM and 6:MM both map to 1:MM when converted to Eastern. In order for
|
||||
:meth:`astimezone` to make this guarantee, the :meth:`tzinfo.dst` method must
|
||||
consider times in the "repeated hour" to be in standard time. This is easily
|
||||
arranged, as in the example, by expressing DST switch times in the time zone's
|
||||
standard local time.
|
||||
form 5:MM and 6:MM both map to 1:MM when converted to Eastern, but earlier times
|
||||
have the :attr:`~datetime.fold` attribute set to 0 and the later times have it set to 1.
|
||||
For example, at the Fall back transition of 2016, we get
|
||||
|
||||
Applications that can't bear such ambiguities should avoid using hybrid
|
||||
>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
|
||||
>>> for i in range(4):
|
||||
... u = u0 + i*HOUR
|
||||
... t = u.astimezone(Eastern)
|
||||
... print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
|
||||
...
|
||||
04:00:00 UTC = 00:00:00 EDT 0
|
||||
05:00:00 UTC = 01:00:00 EDT 0
|
||||
06:00:00 UTC = 01:00:00 EST 1
|
||||
07:00:00 UTC = 02:00:00 EST 0
|
||||
|
||||
Note that the :class:`datetime` instances that differ only by the value of the
|
||||
:attr:`~datetime.fold` attribute are considered equal in comparisons.
|
||||
|
||||
Applications that can't bear wall-time ambiguities should explicitly check the
|
||||
value of the :attr:`~datetime.fold` atribute or avoid using hybrid
|
||||
:class:`tzinfo` subclasses; there are no ambiguities when using :class:`timezone`,
|
||||
or any other fixed-offset :class:`tzinfo` subclass (such as a class representing
|
||||
only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)).
|
||||
|
||||
.. seealso::
|
||||
|
||||
`pytz <https://pypi.python.org/pypi/pytz/>`_
|
||||
`datetuil.tz <https://dateutil.readthedocs.io/en/stable/tz.html>`_
|
||||
The standard library has :class:`timezone` class for handling arbitrary
|
||||
fixed offsets from UTC and :attr:`timezone.utc` as UTC timezone instance.
|
||||
|
||||
*pytz* library brings the *IANA timezone database* (also known as the
|
||||
*datetuil.tz* library brings the *IANA timezone database* (also known as the
|
||||
Olson database) to Python and its usage is recommended.
|
||||
|
||||
`IANA timezone database <https://www.iana.org/time-zones>`_
|
||||
The Time Zone Database (often called tz or zoneinfo) contains code and
|
||||
The Time Zone Database (often called tz, tzdata or zoneinfo) contains code and
|
||||
data that represent the history of local time for many representative
|
||||
locations around the globe. It is updated periodically to reflect changes
|
||||
made by political bodies to time zone boundaries, UTC offsets, and
|
||||
|
@ -1806,7 +1877,7 @@ in different days of the year or where historical changes have been
|
|||
made to civil time.
|
||||
|
||||
|
||||
.. class:: timezone(offset[, name])
|
||||
.. class:: timezone(offset, name=None)
|
||||
|
||||
The *offset* argument must be specified as a :class:`timedelta`
|
||||
object representing the difference between the local time and UTC. It must
|
||||
|
|
Loading…
Reference in New Issue