Search code examples
pythonpandasdatetimepytz

pandas how to override attibute error from timezome localization


I have a idaydf.index that I am trying to localize timezone

DatetimeIndex(['2022-10-24 16:00:00', '2022-10-24 16:15:00',
               ...
               '2023-06-16 21:58:00', '2023-06-16 22:00:00'],
              dtype='datetime64[ns]', name='DateTime', length=9012, freq=None)

with

idaydf.index = idaydf.index.tz_localize(LOCAL_TZ)

where LOCAL_TZ is

_PytzShimTimezone(zoneinfo.ZoneInfo(key='Europe/London'), 'Europe/London')

I get this error:

*** AttributeError: 'NoneType' object has no attribute 'total_seconds'

I have these versions:

python3-3.11.3
pandas-1.5.3
pytz-2023.3-1
tzlocal 4.2

How to fix?


Solution

  • You could use the string representation of the timezone object to decouple. That way,

    • pandas can chose whatever library it wants to handle the timezone (they're supposed to switch from pytz to zoneinfo still in 2023)
    • the library that generates LOCAL_TZ can switch to zoneinfo without crashing your code
    • you can avoid try/excepts

    Ex:

    from zoneinfo import ZoneInfo
    import pytz_deprecation_shim as pds
    import pandas as pd
    
    LOCAL_TZ = pds.timezone('Europe/London')
    print(repr(LOCAL_TZ))
    # _PytzShimTimezone(zoneinfo.ZoneInfo(key='Europe/London'), 'Europe/London')
    
    LOCAL_TZ_new = ZoneInfo('Europe/London')
    print(repr(LOCAL_TZ_new))
    # zoneinfo.ZoneInfo(key='Europe/London')
    
    dti = pd.date_range('2022-10-24 16:00:00', '2023-06-16 22:00:00')
    
    dti0 = dti.tz_localize(str(LOCAL_TZ))
    dti1 = dti.tz_localize(str(LOCAL_TZ_new))
    
    assert (dti0 == dti1).all()
    

    Btw. tzlocal offers a way to directly obtain the IANA tz name as a string, which might make things even easier here -

    from tzlocal import get_localzone_name
    get_localzone_name()
    # "Europe/Berlin" # on my machine...
    

    This works already with tzlocal version 4.2