Skip to content

Commit 522be82

Browse files
author
Neha Jeevan
committed
clarify DST behaviour in datetime arithmetic and zoneinfo
1 parent d6cf05b commit 522be82

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

Doc/library/datetime.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,18 @@ objects.
205205
A :class:`timedelta` object represents a duration, the difference between two
206206
:class:`.datetime` or :class:`date` instances.
207207

208+
.. warning::
209+
210+
When performing arithmetic with aware datetime objects that share the same
211+
``tzinfo`` instance, time zone transitions (such as daylight saving time changes)
212+
are not taken into account. This means the arithmetic may not reflect elapsed
213+
time as measured in UTC. For example, adding one hour across a daylight saving
214+
time boundary may result in a time that is not exactly one hour later in UTC.
215+
216+
For arithmetic that accounts for time zone transitions,
217+
convert the datetime to UTC with :meth:`datetime.astimezone`,
218+
perform the arithmetic, and convert back to the desired time zone.
219+
208220
.. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
209221

210222
All arguments are optional and default to 0. Arguments may be integers
@@ -1289,6 +1301,29 @@ Supported operations:
12891301
object ``t`` such that ``datetime2 + t == datetime1``. No time zone adjustments
12901302
are done in this case.
12911303

1304+
.. note::
1305+
1306+
When two aware datetime objects share the same ``tzinfo`` instance,
1307+
arithmetic is performed in local (naive) time. As a result, differences
1308+
in UTC offset, such as daylight saving time transitions, are not applied.
1309+
1310+
For arithmetic that reflects elapsed time accurately across time zone transitions,
1311+
convert both values to UTC with :meth:`.astimezone`,
1312+
perform arithmetic, and convert back to the desired time zone if needed.
1313+
1314+
Example::
1315+
1316+
>>> from datetime import datetime, timedelta
1317+
>>> from zoneinfo import ZoneInfo
1318+
>>> t = datetime(2024, 10, 27, 1, 0, tzinfo=ZoneInfo("Europe/London"), fold=0)
1319+
>>> t.isoformat()
1320+
'2024-10-27T01:00:00+01:00'
1321+
>>> t + timedelta(hours=1)
1322+
datetime.datetime(2024, 10, 27, 2, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/London'))
1323+
1324+
# This result reflects arithmetic in local time; DST transitions are not applied.
1325+
# The result is not the repeated 01:00 (fold=1), but instead the next distinct clock hour.
1326+
12921327
If both are aware and have different :attr:`~.datetime.tzinfo` attributes, ``a-b`` acts
12931328
as if ``a`` and ``b`` were first converted to naive UTC datetimes. The
12941329
result is ``(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None)

Doc/library/zoneinfo.rst

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,21 @@ method or :meth:`datetime.astimezone <datetime.datetime.astimezone>`::
4949
>>> dt.tzname()
5050
'PDT'
5151

52-
Datetimes constructed in this way are compatible with datetime arithmetic and
53-
handle daylight saving time transitions with no further intervention::
52+
Datetimes constructed in this way are compatible with datetime arithmetic in most cases,
53+
but some operations may not account for daylight saving time transitions as expected.
54+
55+
.. note::
56+
57+
When adding or subtracting a :class:`datetime.timedelta` to a timezone-aware
58+
:class:`datetime.datetime` object using the same :class:`ZoneInfo` instance,
59+
daylight saving time transitions are not accounted for. These operations are
60+
performed in local (naive) time.
61+
62+
To perform arithmetic that accounts for time zone transitions,
63+
convert the datetime object to UTC with :meth:`datetime.astimezone`,
64+
perform the arithmetic, and convert the result back to the local time zone.
65+
66+
.. code-block:: pycon
5467
5568
>>> dt_add = dt + timedelta(days=1)
5669

0 commit comments

Comments
 (0)