pythondatetimeweather

Misaligned dates for cross-day calculations


I have the following function that for a provided date and a pair of lat/long variables is supposed to return the the list of 3 timestamps in UTC

Unfortunately, likely because the calculations jump from one day to another, the results are totally off. Where I got this wrong? Is there a better approach to this?

import datetime as dt
from suntime import Sun

def key_timestamps(date, latitude, longitude):  
    date = dt.datetime.strptime(date, "%Y-%m-%d")
    
    sun = Sun(latitude, longitude)
    
    sunrise = sun.get_sunrise_time(date)
    sunset = sun.get_sunset_time(date)
    
    next_day = date + dt.timedelta(days=1)
    sunrise_next_day = sun.get_sunrise_time(next_day)
    
    solar_noon = sunrise + (sunset - sunrise) / 2
    peak_heating = solar_noon + dt.timedelta(hours=2, minutes=30)
    evening_release = sunset + dt.timedelta(hours=3)
    morning_minimum = sunrise_next_day - dt.timedelta(hours=1)
    
    return [
          int(peak_heating.timestamp()), 
          int(evening_release.timestamp()),
          int(morning_minimum.timestamp())
          ] 

singapore_results = key_timestamps("2022-05-29", 1.3521, 103.8198)
print(singapore_results)

Output is [1653809526, 1653746868, 1653947784] which translates to:

Another example:

la_results = key_timestamps("2022-05-29", 34.0549, 118.2426)

Output:

[1653806070, 1653747048, 1653940656] which translates to:


Solution

  • from datetime import datetime, time, timedelta
    from zoneinfo import ZoneInfo
    from suntime import Sun
    
    def key_timestamps(date, latitude, longitude):  
        sun = Sun(latitude, longitude)
        
        sunrise = sun.get_sunrise_time(date, date.tzinfo)
        sunset = sun.get_sunset_time(date + timedelta(days=1), date.tzinfo)
        sunrise_next_day = sun.get_sunrise_time(date + timedelta(days=1), date.tzinfo)
        
        peak_heating = sunrise + (sunset - sunrise)/2 + timedelta(hours=2, minutes=30)
        evening_release = sunset + timedelta(hours=3)
        morning_minimum = sunrise_next_day - timedelta(hours=1)
        
        return [peak_heating, evening_release, morning_minimum] 
    
    singapore_results = key_timestamps(
        datetime(2022, 5, 29, 0, 0, 0, tzinfo=ZoneInfo("Asia/Singapore")),
        1.3521,
        103.8198,
    )
    print(singapore_results)
    print([int(t.timestamp()) for t in singapore_results])
    

    Outputs:

    [ datetime.datetime(2022, 5, 29, 15, 32, 6, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore')),
      datetime.datetime(2022, 5, 29, 22, 7, 48, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore')),
      datetime.datetime(2022, 5, 30, 5, 56, 24, tzinfo=zoneinfo.ZoneInfo(key='Asia/Singapore'))]
    [1653809526, 1653833268, 1653861384]