SUN_RISE_SET_SPA
This function computes sunrise, sunset, and solar transit times for localized timestamps using the NREL Solar Position Algorithm (SPA).
SPA is a high-accuracy astronomical method used widely in PV and solar-resource workflows where event-timing precision matters.
Conceptually, sunrise and sunset occur near the condition:
\mathrm{zenith} \approx 90^\circ
with corrections from detailed SPA geometry, refraction, and time-scale terms.
Excel Usage
=SUN_RISE_SET_SPA(times, latitude, longitude, delta_t)
times(list[list], required): Timestamps for which to calculate events (ISO8601 format).latitude(float, required): Site latitude (degrees).longitude(float, required): Site longitude (degrees).delta_t(float, optional, default: 67): Difference between terrestrial time and UT1 (seconds).
Returns (list[list]): 2D list [[sunrise, sunset, transit]] as ISO8601 strings, or an error string.
Example 1: Solstice events in Golden, CO
Inputs:
| times | latitude | longitude | delta_t |
|---|---|---|---|
| 2024-06-21T12:00:00-06:00 | 39.742 | -105.179 | 67 |
Excel formula:
=SUN_RISE_SET_SPA({"2024-06-21T12:00:00-06:00"}, 39.742, -105.179, 67)
Expected output:
| Result | ||
|---|---|---|
| 2024-06-21T05:33:02.276770560-06:00 | 2024-06-21T20:32:09.189224704-06:00 | 2024-06-21T13:02:42.069548544-06:00 |
Example 2: Winter solstice events in Golden, CO
Inputs:
| times | latitude | longitude | delta_t |
|---|---|---|---|
| 2024-12-21T12:00:00-07:00 | 39.742 | -105.179 | 67 |
Excel formula:
=SUN_RISE_SET_SPA({"2024-12-21T12:00:00-07:00"}, 39.742, -105.179, 67)
Expected output:
| Result | ||
|---|---|---|
| 2024-12-21T07:18:31.492916224-07:00 | 2024-12-21T16:39:47.010416128-07:00 | 2024-12-21T11:59:09.093026048-07:00 |
Example 3: Equinox events in Golden, CO
Inputs:
| times | latitude | longitude | delta_t |
|---|---|---|---|
| 2024-03-20T12:00:00-06:00 | 39.742 | -105.179 | 67 |
Excel formula:
=SUN_RISE_SET_SPA({"2024-03-20T12:00:00-06:00"}, 39.742, -105.179, 67)
Expected output:
| Result | ||
|---|---|---|
| 2024-03-20T07:03:07.839649792-06:00 | 2024-03-20T19:12:23.359081216-06:00 | 2024-03-20T13:07:56.168577536-06:00 |
Example 4: Scalar timestamp SPA events
Inputs:
| times | latitude | longitude | delta_t |
|---|---|---|---|
| 2024-06-21T12:00:00-06:00 | 39.742 | -105.179 | 67 |
Excel formula:
=SUN_RISE_SET_SPA("2024-06-21T12:00:00-06:00", 39.742, -105.179, 67)
Expected output:
| Result | ||
|---|---|---|
| 2024-06-21T05:33:02.276770560-06:00 | 2024-06-21T20:32:09.189224704-06:00 | 2024-06-21T13:02:42.069548544-06:00 |
Python Code
Show Code
import pandas as pd
from pvlib.solarposition import sun_rise_set_transit_spa as result_func
def sun_rise_set_spa(times, latitude, longitude, delta_t=67):
"""
Calculate sunrise, sunset, and solar transit times using the NREL SPA algorithm.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.solarposition.sun_rise_set_transit_spa.html
This example function is provided as-is without any representation of accuracy.
Args:
times (list[list]): Timestamps for which to calculate events (ISO8601 format).
latitude (float): Site latitude (degrees).
longitude (float): Site longitude (degrees).
delta_t (float, optional): Difference between terrestrial time and UT1 (seconds). Default is 67.
Returns:
list[list]: 2D list [[sunrise, sunset, transit]] as ISO8601 strings, or an error string.
"""
try:
def flatten_str(data):
if not isinstance(data, list): return [str(data)]
return [str(val) for row in data for val in (row if isinstance(row, list) else [row]) if val != ""]
time_list = flatten_str(times)
if len(time_list) == 0:
return "Error: times array cannot be empty"
lat = float(latitude)
lon = float(longitude)
dt = float(delta_t) if delta_t is not None else 67.0
idx = pd.DatetimeIndex(time_list)
res = result_func(
times=idx,
latitude=lat,
longitude=lon,
delta_t=dt
)
# res is a DataFrame with columns: sunrise, sunset, transit
out = []
for i in range(len(idx)):
sr = res['sunrise'].iloc[i]
ss = res['sunset'].iloc[i]
tr = res['transit'].iloc[i]
out.append([
sr.isoformat() if not pd.isna(sr) else "",
ss.isoformat() if not pd.isna(ss) else "",
tr.isoformat() if not pd.isna(tr) else ""
])
return out
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Timestamps for which to calculate events (ISO8601 format).
Site latitude (degrees).
Site longitude (degrees).
Difference between terrestrial time and UT1 (seconds).