[Python] Adding timedelta to local datetime, unexpected behaviour across DST shift

Discussão em 'Python' iniciado por Stack, Novembro 21, 2025.

  1. Stack

    Stack Membro Participativo

    I just stumbled accross this surprising behaviour with Python datetimes while creating datetimes across DST shift.

    Adding a timedelta to a local datetime might not add the amount of time we expect.

    import datetime as dt
    from zoneinfo import ZoneInfo

    # Midnight
    d0 = dt.datetime(2020, 3, 29, 0, 0, tzinfo=ZoneInfo("Europe/Paris"))
    # datetime.datetime(2020, 3, 29, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))
    d0.isoformat()
    # '2020-03-29T00:00:00+01:00'

    # Before DST shift
    d1 = d0 + dt.timedelta(hours=2)
    # datetime.datetime(2020, 3, 29, 2, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))
    d1.isoformat()
    # '2020-03-29T02:00:00+01:00'

    # After DST shift
    d2 = d0 + dt.timedelta(hours=3)
    # datetime.datetime(2020, 3, 29, 3, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))
    d2.isoformat()
    # '2020-03-29T03:00:00+02:00'

    # Convert to UCT
    d1u = d1.astimezone(dt.timezone.utc)
    # datetime.datetime(2020, 3, 29, 1, 0, tzinfo=datetime.timezone.utc)
    d2u = d2.astimezone(dt.timezone.utc)
    # datetime.datetime(2020, 3, 29, 1, 0, tzinfo=datetime.timezone.utc)

    # Compute timedeltas
    d2 - d1
    # datetime.timedelta(seconds=3600)
    d2u - d1u
    # datetime.timedelta(0)


    I agree d1 and d2 are the same, but shouldn't d2 be '2020-03-29T04:00:00+02:00', then?

    d3 = d0 + dt.timedelta(hours=4)
    # datetime.datetime(2020, 3, 29, 4, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))


    Apparently, when adding a timedelta (e.g. 3 hours) to a local datetime, it is added regardless of the timezone and the delta between the two datetimes (in real time / UTC) is not guaranteed to be that timedelta (i.e. it may be 2 hours due to DST). This is a bit of a pitfall.

    What is the rationale? Is this documented somewhere?

    Continue reading...

Compartilhe esta Página