kylebarron / suncalc-py

A Python port of suncalc.js for calculating sun position and sunlight phases
MIT License
60 stars 8 forks source link

DataFrame argument returns wrong solar positions #14

Open nmaslarinos opened 10 months ago

nmaslarinos commented 10 months ago

When using DataFrame arguments in the get_positions functions, the resulting solar positions are shifted by one hour compared to calling the function in a loop with singular datetime arguments. I double-checked the validity of the results using sunclac. The mistake appears to be in the to_milliseconds function.

Here's the code for the singular datetime loop:

import datetime
for i in range(8, 18):
    date = datetime.datetime(2023, 11, 3, i, 00)
    centroid_dict = {
        'lng' = 6.6
        'lat' = 46.5
    }
    azimuth, altitude = suncalc.get_position(date, **centroid_dict).values()

and here is the code creating a DataFrame and passing its elements as arguments:

import datetime
datetimes = []
    for hour in range(8, 18):
        datetimes.append(datetime.datetime(2023, 11, 3, hour))
df = pd.DataFrame({
    'date': datetimes,
    'lon': 6.6* len(datetimes),
    'lat': 46.5 * len(datetimes),
})
positions = suncalc.get_position(df["date"], lat=df["lat"], lng=df["lon"])

The first snippet returns the following results:

Solar altitude for 2023-11-03 08:00:00 is 5.842° (0.102rad) and azimuth is -61.096° (-1.066rad)
Solar altitude for 2023-11-03 09:00:00 is 14.287° (0.249rad) and azimuth is -49.119° (-0.857rad)
Solar altitude for 2023-11-03 10:00:00 is 21.236° (0.371rad) and azimuth is -35.750° (-0.624rad)
Solar altitude for 2023-11-03 11:00:00 is 26.118° (0.456rad) and azimuth is -20.837° (-0.364rad)
Solar altitude for 2023-11-03 12:00:00 is 28.391° (0.496rad) and azimuth is -4.724° (-0.082rad)
Solar altitude for 2023-11-03 13:00:00 is 27.749° (0.484rad) and azimuth is 11.695° (0.204rad)
Solar altitude for 2023-11-03 14:00:00 is 24.283° (0.424rad) and azimuth is 27.364° (0.478rad)
Solar altitude for 2023-11-03 15:00:00 is 18.427° (0.322rad) and azimuth is 41.608° (0.726rad)
Solar altitude for 2023-11-03 16:00:00 is 10.757° (0.188rad) and azimuth is 54.321° (0.948rad)
Solar altitude for 2023-11-03 17:00:00 is 1.816° (0.032rad) and azimuth is 65.802° (1.148rad)

while the second one returns the following:

Solar altitude for 2023-11-3  8:00:00 is 14.287° (0.249rad) and azimuth is -49.119° (-0.857rad)
Solar altitude for 2023-11-3  9:00:00 is 21.236° (0.371rad) and azimuth is -35.750° (-0.624rad)
Solar altitude for 2023-11-3 10:00:00 is 26.118° (0.456rad) and azimuth is -20.837° (-0.364rad)
Solar altitude for 2023-11-3 11:00:00 is 28.391° (0.496rad) and azimuth is -4.724° (-0.082rad)
Solar altitude for 2023-11-3 12:00:00 is 27.749° (0.484rad) and azimuth is 11.695° (0.204rad)
Solar altitude for 2023-11-3 13:00:00 is 24.283° (0.424rad) and azimuth is 27.364° (0.478rad)
Solar altitude for 2023-11-3 14:00:00 is 18.427° (0.322rad) and azimuth is 41.608° (0.726rad)
Solar altitude for 2023-11-3 15:00:00 is 10.757° (0.188rad) and azimuth is 54.321° (0.948rad)
Solar altitude for 2023-11-3 16:00:00 is 1.816° (0.032rad) and azimuth is 65.802° (1.148rad)
Solar altitude for 2023-11-3 17:00:00 is -7.944° (-0.139rad) and azimuth is 76.536° (1.336rad)
nmaslarinos commented 9 months ago

I finally managed to figure out the problem, it's because of the lack of timezone info provided. Should I update any datetime object with timezone information, all calculations are the same. Maybe some reference to the need for localised time would help others as well

kylebarron commented 9 months ago

it's because of the lack of timezone info provided

In bold, the docs say

Datetime must be in UTC.

So you probably need to convert the times to UTC initially and then convert the output to your localized location. Any docs updates are welcome