pvlib/pvlib-python

`NonExistentTimeError` when calling `hour_angle`

Opened this issue · 5 comments

Describe the bug

Cannot compute hour_angle in timezones and on a day where a daylight savings transition happens at midnight.

To Reproduce

from datetime import datetime, timedelta
import pytz
import pandas as pd
import pvlib

date = datetime(2014, 9, 7, 0, 0, 0, tzinfo=pytz.UTC)
times = pd.DatetimeIndex(
    [date + timedelta(hours=hour) for hour in range(24)]
).tz_convert("America/Santiago")

day_of_year = date.timetuple().tm_yday

equation_of_time = pvlib.solarposition.equation_of_time_spencer71(day_of_year)
declination = pvlib.solarposition.declination_spencer71(day_of_year)
hour_angle = pvlib.solarposition.hour_angle(
    times, 70.6693, equation_of_time
)

The call to times.normalize() inside hour_angle raises an exception:

pytz.exceptions.NonExistentTimeError: 2014-09-07 00:00:00

Expected behavior

I'm not entirely sure. Pandas' tz_localize includes arguments for handling these sort of situations (https://pandas.pydata.org/docs/reference/api/pandas.Series.dt.tz_localize.html) and I suspect we could normalize the times like this:

tz = times.tz
normalized_times = times.tz_localize(None).normalize().tz_localize(tz, nonexistent="shift_forward")

This would normalize the times to 1:00am instead of 12:00am (which didn't exist on that date). Here's some related discussion from a Pandas issue: pandas-dev/pandas#40517

I suspect we'd need to similarly handle ambiguous times when daylight savings ends.

Does this seem like a reasonable approach? I can put a small PR together if so.

Versions:

  • pvlib.__version__: 0.10.5
  • pandas.__version__: 2.2.2
  • python: 3.11.7

Confirmed the issue with pvlib v0.11.0.

The discussion around the pandas issue suggests this occurs when DST adjustment occurs in a way that midnight local never "happens".

Short of a worldwide deprecation of daylight savings times, or handling of this case by pandas.normalize, I suppose we ought to patch pvlib with liberal comments. rdtools worked around the problem in the similar way as proposed here https://github.com/NREL/rdtools/pull/373/files

@scttnlsn re-reading my comment, I don't think I was very clear: PR welcome along the lines you propose.

@cwhanse Sounds good - I'll put something together

@scttnlsn don't hesitate to reach out if you need help getting started with GitHub or the likes 😄

@AdamRJensen There's a PR open here: #2133 Let me know if anything needs more attention before merging.