• [x] I have checked that this issue has not already been reported.

  • [x] I have confirmed this bug exists on the latest version of pandas.

  • [ ] (optional) I have confirmed this bug exists on the master branch of pandas.


Code Sample, a copy-pastable example

s = pd.Series(range(2),
              index=pd.DatetimeIndex(['2021-03-28 01:30:00',
                                      '2021-03-28 02:30:00']))
s.tz_localize('Europe/London', nonexistent=pd.Timedelta('1H'))
2021-03-28 03:30:00+01:00    0
2021-03-28 02:30:00+01:00    1
dtype: int64

Problem description

Using Timedelta with the nonexistent flag with tz_localize is adding 2 hours instead of 1 hour for nonexistent times in 'Europe/London' tz. DST started on 2021-03-28 when 59:59 > 02:00 so '2021-03-28 01:30:00' is nonexistent. When I run almost the same code from the docs with 'Europe/Warsaw' the bug does not occur:

s = pd.Series(range(2),
              index=pd.DatetimeIndex(['2021-03-28 02:30:00',
                                      '2021-03-28 03:30:00']))
s.tz_localize('Europe/Warsaw', nonexistent=pd.Timedelta('1H'))
2021-03-28 03:30:00+02:00    0
2021-03-28 03:30:00+02:00    1
dtype: int64

Expected Output

2021-03-28 02:30:00+01:00    0
2021-03-28 02:30:00+01:00    1
dtype: int64

Output of pd.show_versions()

INSTALLED VERSIONS ------------------ commit : f2c8480af2f25efdbd803218b9d87980f416563e python : 3.8.7.final.0 python-bits : 64 OS : Windows OS-release : 10 Version : 10.0.18362 machine : AMD64 processor : Intel64 Family 6 Model 158 Stepping 9, GenuineIntel byteorder : little LC_ALL : None LANG : None LOCALE : English_United Kingdom.1252 pandas : 1.2.3 numpy : 1.19.5 pytz : 2020.5 dateutil : 2.8.1 pip : 20.3.3 setuptools : 51.1.2 Cython : None pytest : None hypothesis : None sphinx : None blosc : None feather : None xlsxwriter : None lxml.etree : None html5lib : None pymysql : None psycopg2 : None jinja2 : 2.11.2 IPython : 7.19.0 pandas_datareader: None bs4 : None bottleneck : None fsspec : None fastparquet : None gcsfs : None matplotlib : None numexpr : None odfpy : None openpyxl : 3.0.6 pandas_gbq : None pyarrow : 2.0.0 pyxlsb : None s3fs : None scipy : None sqlalchemy : None tables : None tabulate : None xarray : None xlrd : None xlwt : None numba : None

Comment From: mroeschke

Thanks for the report. I suspect this has the same underlying issue as https://github.com/pandas-dev/pandas/issues/40915

Comment From: thomie

This issue, just like #40915, seems to be fixed (I only tested with version 2.3.1):

>>> s = pd.Series(range(2), index=pd.DatetimeIndex(['2021-03-28 01:30:00', '2021-03-28 02:30:00']))
>>> s.tz_localize('Europe/London', nonexistent=pd.Timedelta('1h'))
2021-03-28 02:30:00+01:00    0
2021-03-28 02:30:00+01:00    1
dtype: int64 

Output of pd.show_versions()

Details INSTALLED VERSIONS ------------------ commit : c888af6d0bb674932007623c0867e1fbd4bdc2c6 python : 3.12.11 python-bits : 64 OS : Linux OS-release : 6.12.41 Version : #1-NixOS SMP PREEMPT_DYNAMIC Fri Aug 1 08:48:47 UTC 2025 machine : x86_64 processor : byteorder : little LC_ALL : None LANG : en_US.UTF-8 LOCALE : en_US.UTF-8 pandas : 2.3.1 numpy : 2.3.1 pytz : 2025.2 dateutil : 2.9.0.post0 pip : None Cython : None sphinx : None IPython : 9.4.0 adbc-driver-postgresql: None adbc-driver-sqlite : None bs4 : None blosc : None bottleneck : None dataframe-api-compat : None fastparquet : None fsspec : None html5lib : None hypothesis : None gcsfs : None jinja2 : None lxml.etree : None matplotlib : None numba : None numexpr : None odfpy : None openpyxl : None pandas_gbq : None psycopg2 : None pymysql : None pyarrow : 20.0.0 pyreadstat : None pytest : 8.4.1 python-calamine : None pyxlsb : None s3fs : None scipy : None sqlalchemy : 2.0.42 tables : None tabulate : None xarray : None xlrd : None xlsxwriter : None zstandard : None tzdata : 2025.2 qtpy : None pyqt5 : None