Docs: import datetime as dt in examples (#145315)

This commit is contained in:
Hugo van Kemenade 2026-03-06 13:18:11 +02:00 committed by GitHub
parent 349639cfa4
commit d3b6faf975
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 224 additions and 206 deletions

View file

@ -1,68 +1,70 @@
from datetime import tzinfo, timedelta, datetime
ZERO = timedelta(0)
HOUR = timedelta(hours=1)
SECOND = timedelta(seconds=1)
import datetime as dt
# 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
import time
STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds = -_time.altzone)
ZERO = dt.timedelta(0)
HOUR = dt.timedelta(hours=1)
SECOND = dt.timedelta(seconds=1)
STDOFFSET = dt.timedelta(seconds=-time.timezone)
if time.daylight:
DSTOFFSET = dt.timedelta(seconds=-time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
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]
class LocalTimezone(dt.tzinfo):
def fromutc(self, when):
assert when.tzinfo is self
stamp = (when - 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)
fold = (args == time.localtime(stamp - dst_diff))
return dt.datetime(*args, microsecond=when.microsecond,
tzinfo=self, fold=fold)
def utcoffset(self, dt):
if self._isdst(dt):
def utcoffset(self, when):
if self._isdst(when):
return DSTOFFSET
else:
return STDOFFSET
def dst(self, dt):
if self._isdst(dt):
def dst(self, when):
if self._isdst(when):
return DSTDIFF
else:
return ZERO
def tzname(self, dt):
return _time.tzname[self._isdst(dt)]
def tzname(self, when):
return time.tzname[self._isdst(when)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, 0)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
def _isdst(self, when):
tt = (when.year, when.month, when.day,
when.hour, when.minute, when.second,
when.weekday(), 0, 0)
stamp = time.mktime(tt)
tt = time.localtime(stamp)
return tt.tm_isdst > 0
Local = LocalTimezone()
# A complete implementation of current DST rules for major US time zones.
def first_sunday_on_or_after(dt):
days_to_go = 6 - dt.weekday()
def first_sunday_on_or_after(when):
days_to_go = 6 - when.weekday()
if days_to_go:
dt += timedelta(days_to_go)
return dt
when += dt.timedelta(days_to_go)
return when
# US DST Rules
@ -75,21 +77,22 @@ 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)
DSTSTART_2007 = dt.datetime(1, 3, 8, 2)
# and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 2)
DSTEND_2007 = dt.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) 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, 2)
DSTSTART_1987_2006 = dt.datetime(1, 4, 1, 2)
DSTEND_1987_2006 = dt.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)
# on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTSTART_1967_1986 = dt.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.
@ -100,17 +103,17 @@ def us_dst_range(year):
elif 1966 < year < 1987:
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
else:
return (datetime(year, 1, 1), ) * 2
return (dt.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):
class USTimeZone(dt.tzinfo):
def __init__(self, hours, reprname, stdname, dstname):
self.stdoffset = timedelta(hours=hours)
self.stdoffset = dt.timedelta(hours=hours)
self.reprname = reprname
self.stdname = stdname
self.dstname = dstname
@ -118,45 +121,45 @@ def __init__(self, hours, reprname, stdname, dstname):
def __repr__(self):
return self.reprname
def tzname(self, dt):
if self.dst(dt):
def tzname(self, when):
if self.dst(when):
return self.dstname
else:
return self.stdname
def utcoffset(self, dt):
return self.stdoffset + self.dst(dt)
def utcoffset(self, when):
return self.stdoffset + self.dst(when)
def dst(self, dt):
if dt is None or dt.tzinfo is None:
def dst(self, when):
if when is None or when.tzinfo is None:
# An exception may be sensible here, in one or both cases.
# It depends on how you want to treat them. The default
# fromutc() implementation (called by the default astimezone()
# implementation) passes a datetime with dt.tzinfo is self.
# implementation) passes a datetime with when.tzinfo is self.
return ZERO
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
assert when.tzinfo is self
start, end = us_dst_range(when.year)
# Can't compare naive to aware objects, so strip the timezone from
# dt first.
dt = dt.replace(tzinfo=None)
if start + HOUR <= dt < end - HOUR:
# when first.
when = when.replace(tzinfo=None)
if start + HOUR <= when < end - HOUR:
# DST is in effect.
return HOUR
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:
if end - HOUR <= when < end:
# Fold (an ambiguous hour): use when.fold to disambiguate.
return ZERO if when.fold else HOUR
if start <= when < start + HOUR:
# Gap (a non-existent hour): reverse the fold rule.
return HOUR if dt.fold else ZERO
return HOUR if when.fold else ZERO
# DST is off.
return ZERO
def fromutc(self, dt):
assert dt.tzinfo is self
start, end = us_dst_range(dt.year)
def fromutc(self, when):
assert when.tzinfo is self
start, end = us_dst_range(when.year)
start = start.replace(tzinfo=self)
end = end.replace(tzinfo=self)
std_time = dt + self.stdoffset
std_time = when + self.stdoffset
dst_time = std_time + HOUR
if end <= dst_time < end + HOUR:
# Repeated hour

View file

@ -230,8 +230,8 @@ A :class:`timedelta` object represents a duration, the difference between two
*days*, *seconds* and *microseconds* are "merged" and normalized into those
three resulting attributes::
>>> from datetime import timedelta
>>> delta = timedelta(
>>> import datetime as dt
>>> delta = dt.timedelta(
... days=50,
... seconds=27,
... microseconds=10,
@ -244,6 +244,12 @@ A :class:`timedelta` object represents a duration, the difference between two
>>> delta
datetime.timedelta(days=64, seconds=29156, microseconds=10)
.. tip::
``import datetime as dt`` instead of ``import datetime`` or
``from datetime import datetime`` to avoid confusion between the module
and the class. See `How I Import Pythons datetime Module
<https://adamj.eu/tech/2019/09/12/how-i-import-pythons-datetime-module/>`__.
If any argument is a float and there are fractional microseconds,
the fractional microseconds left over from all arguments are
combined and their sum is rounded to the nearest microsecond using
@ -257,8 +263,8 @@ A :class:`timedelta` object represents a duration, the difference between two
Note that normalization of negative values may be surprising at first. For
example::
>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> import datetime as dt
>>> d = dt.timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)
@ -321,8 +327,8 @@ Instance attributes (read-only):
.. doctest::
>>> from datetime import timedelta
>>> duration = timedelta(seconds=11235813)
>>> import datetime as dt
>>> duration = dt.timedelta(seconds=11235813)
>>> duration.days, duration.seconds
(130, 3813)
>>> duration.total_seconds()
@ -461,10 +467,10 @@ Examples of usage: :class:`!timedelta`
An additional example of normalization::
>>> # Components of another_year add up to exactly 365 days
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600)
>>> import datetime as dt
>>> year = dt.timedelta(days=365)
>>> another_year = dt.timedelta(weeks=40, days=84, hours=23,
... minutes=50, seconds=600)
>>> year == another_year
True
>>> year.total_seconds()
@ -472,8 +478,8 @@ An additional example of normalization::
Examples of :class:`timedelta` arithmetic::
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> import datetime as dt
>>> year = dt.timedelta(days=365)
>>> ten_years = 10 * year
>>> ten_years
datetime.timedelta(days=3650)
@ -565,12 +571,12 @@ Other constructors, all class methods:
Examples::
>>> from datetime import date
>>> date.fromisoformat('2019-12-04')
>>> import datetime as dt
>>> dt.date.fromisoformat('2019-12-04')
datetime.date(2019, 12, 4)
>>> date.fromisoformat('20191204')
>>> dt.date.fromisoformat('20191204')
datetime.date(2019, 12, 4)
>>> date.fromisoformat('2021-W01-1')
>>> dt.date.fromisoformat('2021-W01-1')
datetime.date(2021, 1, 4)
.. versionadded:: 3.7
@ -611,9 +617,9 @@ Other constructors, all class methods:
.. doctest::
>>> from datetime import date
>>> import datetime as dt
>>> date_string = "02/29"
>>> when = date.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug.
>>> when = dt.date.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug.
>>> when.strftime("%B %d") # doctest: +SKIP
'February 29'
@ -728,8 +734,8 @@ Instance methods:
Example::
>>> from datetime import date
>>> d = date(2002, 12, 31)
>>> import datetime as dt
>>> d = dt.date(2002, 12, 31)
>>> d.replace(day=26)
datetime.date(2002, 12, 26)
@ -787,10 +793,10 @@ Instance methods:
For example, 2004 begins on a Thursday, so the first week of ISO year 2004
begins on Monday, 29 Dec 2003 and ends on Sunday, 4 Jan 2004::
>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
>>> import datetime as dt
>>> dt.date(2003, 12, 29).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=1)
>>> date(2004, 1, 4).isocalendar()
>>> dt.date(2004, 1, 4).isocalendar()
datetime.IsoCalendarDate(year=2004, week=1, weekday=7)
.. versionchanged:: 3.9
@ -801,8 +807,8 @@ Instance methods:
Return a string representing the date in ISO 8601 format, ``YYYY-MM-DD``::
>>> from datetime import date
>>> date(2002, 12, 4).isoformat()
>>> import datetime as dt
>>> dt.date(2002, 12, 4).isoformat()
'2002-12-04'
@ -815,8 +821,8 @@ Instance methods:
Return a string representing the date::
>>> from datetime import date
>>> date(2002, 12, 4).ctime()
>>> import datetime as dt
>>> dt.date(2002, 12, 4).ctime()
'Wed Dec 4 00:00:00 2002'
``d.ctime()`` is equivalent to::
@ -849,13 +855,13 @@ Examples of usage: :class:`!date`
Example of counting days to an event::
>>> import time
>>> from datetime import date
>>> today = date.today()
>>> import datetime as dt
>>> today = dt.date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
>>> today == dt.date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> my_birthday = dt.date(today.year, 6, 24)
>>> if my_birthday < today:
... my_birthday = my_birthday.replace(year=today.year + 1)
...
@ -869,8 +875,8 @@ More examples of working with :class:`date`:
.. doctest::
>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> import datetime as dt
>>> d = dt.date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)
@ -1123,24 +1129,24 @@ Other constructors, all class methods:
Examples::
>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
>>> import datetime as dt
>>> dt.datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('20111104')
>>> dt.datetime.fromisoformat('20111104')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23')
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04T00:05:23Z')
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23Z')
datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('20111104T000523')
>>> dt.datetime.fromisoformat('20111104T000523')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-W01-2T00:05:23.283')
>>> dt.datetime.fromisoformat('2011-W01-2T00:05:23.283')
datetime.datetime(2011, 1, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283')
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
>>> dt.datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') # doctest: +NORMALIZE_WHITESPACE
>>> dt.datetime.fromisoformat('2011-11-04T00:05:23+04:00') # doctest: +NORMALIZE_WHITESPACE
datetime.datetime(2011, 11, 4, 0, 5, 23,
tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
@ -1187,9 +1193,9 @@ Other constructors, all class methods:
.. doctest::
>>> from datetime import datetime
>>> import datetime as dt
>>> date_string = "02/29"
>>> when = datetime.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug.
>>> when = dt.datetime.strptime(f"{date_string};1984", "%m/%d;%Y") # Avoids leap year bug.
>>> when.strftime("%B %d") # doctest: +SKIP
'February 29'
@ -1599,24 +1605,24 @@ Instance methods:
Examples::
>>> from datetime import datetime, timezone
>>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat()
>>> import datetime as dt
>>> dt.datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat()
'2019-05-18T15:17:08.132263'
>>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat()
>>> dt.datetime(2019, 5, 18, 15, 17, tzinfo=dt.timezone.utc).isoformat()
'2019-05-18T15:17:00+00:00'
The optional argument *sep* (default ``'T'``) is a one-character separator,
placed between the date and time portions of the result. For example::
>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
>>> import datetime as dt
>>> class TZ(dt.tzinfo):
... """A time zone with an arbitrary, constant -06:39 offset."""
... def utcoffset(self, dt):
... return timedelta(hours=-6, minutes=-39)
... def utcoffset(self, when):
... return dt.timedelta(hours=-6, minutes=-39)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
>>> dt.datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
>>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat()
>>> dt.datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat()
'2009-11-27T00:00:00.000100-06:39'
The optional argument *timespec* specifies the number of additional
@ -1640,11 +1646,11 @@ Instance methods:
:exc:`ValueError` will be raised on an invalid *timespec* argument::
>>> from datetime import datetime
>>> datetime.now().isoformat(timespec='minutes') # doctest: +SKIP
>>> import datetime as dt
>>> dt.datetime.now().isoformat(timespec='minutes') # doctest: +SKIP
'2002-12-25T00:00'
>>> dt = datetime(2015, 1, 1, 12, 30, 59, 0)
>>> dt.isoformat(timespec='microseconds')
>>> my_datetime = dt.datetime(2015, 1, 1, 12, 30, 59, 0)
>>> my_datetime.isoformat(timespec='microseconds')
'2015-01-01T12:30:59.000000'
.. versionchanged:: 3.6
@ -1661,8 +1667,8 @@ Instance methods:
Return a string representing the date and time::
>>> from datetime import datetime
>>> datetime(2002, 12, 4, 20, 30, 40).ctime()
>>> import datetime as dt
>>> dt.datetime(2002, 12, 4, 20, 30, 40).ctime()
'Wed Dec 4 20:30:40 2002'
The output string will *not* include time zone information, regardless
@ -1699,27 +1705,27 @@ Examples of working with :class:`.datetime` objects:
.. doctest::
>>> from datetime import datetime, date, time, timezone
>>> import datetime as dt
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
>>> d = dt.date(2005, 7, 14)
>>> t = dt.time(12, 30)
>>> dt.datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now()
>>> datetime.now() # doctest: +SKIP
>>> dt.datetime.now() # doctest: +SKIP
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043) # GMT +1
>>> datetime.now(timezone.utc) # doctest: +SKIP
>>> dt.datetime.now(dt.timezone.utc) # doctest: +SKIP
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
>>> my_datetime = dt.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> my_datetime
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> tt = my_datetime.timetuple()
>>> for it in tt: # doctest: +SKIP
... print(it)
...
@ -1734,7 +1740,7 @@ Examples of working with :class:`.datetime` objects:
-1 # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> ic = my_datetime.isocalendar()
>>> for it in ic: # doctest: +SKIP
... print(it)
...
@ -1743,55 +1749,55 @@ Examples of working with :class:`.datetime` objects:
2 # ISO weekday
>>> # Formatting a datetime
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
>>> my_datetime.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time")
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(my_datetime, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'
The example below defines a :class:`tzinfo` subclass capturing time zone
information for Kabul, Afghanistan, which used +4 UTC until 1945
and then +4:30 UTC thereafter::
from datetime import timedelta, datetime, tzinfo, timezone
import datetime as dt
class KabulTz(tzinfo):
class KabulTz(dt.tzinfo):
# Kabul used +4 until 1945, when they moved to +4:30
UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc)
UTC_MOVE_DATE = dt.datetime(1944, 12, 31, 20, tzinfo=dt.timezone.utc)
def utcoffset(self, dt):
if dt.year < 1945:
return timedelta(hours=4)
elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30):
def utcoffset(self, when):
if when.year < 1945:
return dt.timedelta(hours=4)
elif (1945, 1, 1, 0, 0) <= when.timetuple()[:5] < (1945, 1, 1, 0, 30):
# An ambiguous ("imaginary") half-hour range representing
# a 'fold' in time due to the shift from +4 to +4:30.
# If dt falls in the imaginary range, use fold to decide how
# to resolve. See PEP495.
return timedelta(hours=4, minutes=(30 if dt.fold else 0))
# If when falls in the imaginary range, use fold to decide how
# to resolve. See PEP 495.
return dt.timedelta(hours=4, minutes=(30 if when.fold else 0))
else:
return timedelta(hours=4, minutes=30)
return dt.timedelta(hours=4, minutes=30)
def fromutc(self, dt):
def fromutc(self, when):
# Follow same validations as in datetime.tzinfo
if not isinstance(dt, datetime):
if not isinstance(when, dt.datetime):
raise TypeError("fromutc() requires a datetime argument")
if dt.tzinfo is not self:
raise ValueError("dt.tzinfo is not self")
if when.tzinfo is not self:
raise ValueError("when.tzinfo is not self")
# A custom implementation is required for fromutc as
# the input to this function is a datetime with utc values
# but with a tzinfo set to self.
# See datetime.astimezone or fromtimestamp.
if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE:
return dt + timedelta(hours=4, minutes=30)
if when.replace(tzinfo=dt.timezone.utc) >= self.UTC_MOVE_DATE:
return when + dt.timedelta(hours=4, minutes=30)
else:
return dt + timedelta(hours=4)
return when + dt.timedelta(hours=4)
def dst(self, dt):
def dst(self, when):
# Kabul does not observe daylight saving time.
return timedelta(0)
return dt.timedelta(0)
def tzname(self, dt):
if dt >= self.UTC_MOVE_DATE:
def tzname(self, when):
if when >= self.UTC_MOVE_DATE:
return "+04:30"
return "+04"
@ -1800,17 +1806,17 @@ Usage of ``KabulTz`` from above::
>>> tz1 = KabulTz()
>>> # Datetime before the change
>>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> dt1 = dt.datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
>>> print(dt1.utcoffset())
4:00:00
>>> # Datetime after the change
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> dt2 = dt.datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
>>> print(dt2.utcoffset())
4:30:00
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(timezone.utc)
>>> dt3 = dt2.astimezone(dt.timezone.utc)
>>> dt3
datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc)
>>> dt2
@ -1946,22 +1952,22 @@ Other constructors:
.. doctest::
>>> from datetime import time
>>> time.fromisoformat('04:23:01')
>>> import datetime as dt
>>> dt.time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('T04:23:01')
>>> dt.time.fromisoformat('T04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('T042301')
>>> dt.time.fromisoformat('T042301')
datetime.time(4, 23, 1)
>>> time.fromisoformat('04:23:01.000384')
>>> dt.time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> time.fromisoformat('04:23:01,000384')
>>> dt.time.fromisoformat('04:23:01,000384')
datetime.time(4, 23, 1, 384)
>>> time.fromisoformat('04:23:01+04:00')
>>> dt.time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
>>> time.fromisoformat('04:23:01Z')
>>> dt.time.fromisoformat('04:23:01Z')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
>>> time.fromisoformat('04:23:01+00:00')
>>> dt.time.fromisoformat('04:23:01+00:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc)
@ -2036,13 +2042,13 @@ Instance methods:
Example::
>>> from datetime import time
>>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
>>> import datetime as dt
>>> dt.time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
'12:34'
>>> dt = time(hour=12, minute=34, second=56, microsecond=0)
>>> dt.isoformat(timespec='microseconds')
>>> my_time = dt.time(hour=12, minute=34, second=56, microsecond=0)
>>> my_time.isoformat(timespec='microseconds')
'12:34:56.000000'
>>> dt.isoformat(timespec='auto')
>>> my_time.isoformat(timespec='auto')
'12:34:56'
.. versionchanged:: 3.6
@ -2100,18 +2106,18 @@ Examples of usage: :class:`!time`
Examples of working with a :class:`.time` object::
>>> from datetime import time, tzinfo, timedelta
>>> class TZ1(tzinfo):
... def utcoffset(self, dt):
... return timedelta(hours=1)
... def dst(self, dt):
... return timedelta(0)
... def tzname(self,dt):
>>> import datetime as dt
>>> class TZ1(dt.tzinfo):
... def utcoffset(self, when):
... return dt.timedelta(hours=1)
... def dst(self, when):
... return dt.timedelta(0)
... def tzname(self, when):
... return "+01:00"
... def __repr__(self):
... return f"{self.__class__.__name__}()"
...
>>> t = time(12, 10, 30, tzinfo=TZ1())
>>> t = dt.time(12, 10, 30, tzinfo=TZ1())
>>> t
datetime.time(12, 10, 30, tzinfo=TZ1())
>>> t.isoformat()
@ -2219,21 +2225,25 @@ Examples of working with a :class:`.time` object::
Most implementations of :meth:`dst` will probably look like one of these two::
def dst(self, dt):
import datetime as dt
def dst(self, when):
# a fixed-offset class: doesn't account for DST
return timedelta(0)
return dt.timedelta(0)
or::
def dst(self, dt):
import datetime as dt
def dst(self, when):
# Code to set dston and dstoff to the time zone's DST
# transition times based on the input dt.year, and expressed
# transition times based on the input when.year, and expressed
# in standard local time.
if dston <= dt.replace(tzinfo=None) < dstoff:
return timedelta(hours=1)
if dston <= when.replace(tzinfo=None) < dstoff:
return dt.timedelta(hours=1)
else:
return timedelta(0)
return dt.timedelta(0)
The default implementation of :meth:`dst` raises :exc:`NotImplementedError`.
@ -2299,20 +2309,22 @@ There is one more :class:`tzinfo` method that a subclass may wish to override:
Skipping code for error cases, the default :meth:`fromutc` implementation acts
like::
def fromutc(self, dt):
# raise ValueError error if dt.tzinfo is not self
dtoff = dt.utcoffset()
dtdst = dt.dst()
import datetime as dt
def fromutc(self, when):
# raise ValueError error if when.tzinfo is not self
dtoff = when.utcoffset()
dtdst = when.dst()
# raise ValueError if dtoff is None or dtdst is None
delta = dtoff - dtdst # this is self's standard offset
if delta:
dt += delta # convert to standard local time
dtdst = dt.dst()
when += delta # convert to standard local time
dtdst = when.dst()
# raise ValueError if dtdst is None
if dtdst:
return dt + dtdst
return when + dtdst
else:
return dt
return when
In the following :download:`tzinfo_examples.py
<../includes/tzinfo_examples.py>` file there are some examples of
@ -2339,9 +2351,9 @@ When DST starts (the "start" line), the local wall clock leaps from 1:59 to
``astimezone(Eastern)`` won't deliver a result with ``hour == 2`` on the day DST
begins. For example, at the Spring forward transition of 2016, we get::
>>> from datetime import datetime, timezone
>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc)
>>> u0 = dt.datetime(2016, 3, 13, 5, tzinfo=dt.timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
@ -2364,7 +2376,9 @@ 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::
>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> import datetime as dt
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = dt.datetime(2016, 11, 6, 4, tzinfo=dt.timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
@ -2515,8 +2529,9 @@ versus :meth:`~.datetime.strptime`:
These methods accept format codes that can be used to parse and format dates::
>>> datetime.strptime('31/01/22 23:59:59.999999',
... '%d/%m/%y %H:%M:%S.%f')
>>> import datetime as dt
>>> dt.datetime.strptime('31/01/22 23:59:59.999999',
... '%d/%m/%y %H:%M:%S.%f')
datetime.datetime(2022, 1, 31, 23, 59, 59, 999999)
>>> _.strftime('%a %d %b %Y, %I:%M%p')
'Mon 31 Jan 2022, 11:59PM'
@ -2745,13 +2760,13 @@ in the format string will be pulled from the default value.
.. doctest::
>>> from datetime import datetime
>>> import datetime as dt
>>> value = "2/29"
>>> datetime.strptime(value, "%m/%d")
>>> dt.datetime.strptime(value, "%m/%d")
Traceback (most recent call last):
...
ValueError: day 29 must be in range 1..28 for month 2 in year 1900
>>> datetime.strptime(f"1904 {value}", "%Y %m/%d")
>>> dt.datetime.strptime(f"1904 {value}", "%Y %m/%d")
datetime.datetime(1904, 2, 29, 0, 0)
Using ``datetime.strptime(date_string, format)`` is equivalent to::
@ -2897,7 +2912,7 @@ Notes:
.. doctest::
>>> month_day = "02/29"
>>> datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug.
>>> dt.datetime.strptime(f"{month_day};1984", "%m/%d;%Y") # No leap year bug.
datetime.datetime(1984, 2, 29, 0, 0)
.. deprecated-removed:: 3.13 3.15
@ -2908,7 +2923,7 @@ Notes:
.. rubric:: Footnotes
.. [#] If, that is, we ignore the effects of Relativity
.. [#] If, that is, we ignore the effects of relativity.
.. [#] This matches the definition of the "proleptic Gregorian" calendar in
Dershowitz and Reingold's book *Calendrical Calculations*,