def sunrise_sunset(moment, latitude, longitude): r'''Calculates the times at which the sun is at sunset; sunrise; and halfway between sunrise and sunset (transit). Uses the Reda and Andreas (2004) model described in [1]_, originally incorporated into the excellent `pvlib library <https://github.com/pvlib/pvlib-python>`_ Parameters ---------- moment : datetime Date for the calculation; needs to contain only the year, month, and day, [-] latitude : float Latitude, between -90 and 90 [degrees] longitude : float Longitude, between -180 and 180, [degrees] Returns ------- sunrise : datetime The time at the specified day when the sun rises **IN UTC**, [-] sunset : datetime The time at the specified day when the sun sets **IN UTC**, [-] transit : datetime The time at the specified day when the sun is at solar noon - halfway between sunrise and sunset **IN UTC**, [-] Examples -------- >>> sunrise, sunset, transit = sunrise_sunset(datetime(2018, 4, 17), ... 51.0486, -114.07) >>> sunrise datetime.datetime(2018, 4, 17, 12, 36, 55, 782660) >>> sunset datetime.datetime(2018, 4, 18, 2, 34, 4, 249326) >>> transit datetime.datetime(2018, 4, 17, 19, 35, 46, 686265) Notes ----- This functions takes on the order of 2 ms per calculation. The reason the function cannot return the time correct the local timezone is that the function does not know the timezone at the specified lat/long. References ---------- .. [1] Reda, Ibrahim, and Afshin Andreas. "Solar Position Algorithm for Solar Radiation Applications." Solar Energy 76, no. 5 (January 1, 2004): 577-89. https://doi.org/10.1016/j.solener.2003.12.003. ''' from fluids.optional import spa delta_t = spa.calculate_deltat(moment.year, moment.month) # Strip the part of the day moment = datetime(moment.year, moment.month, moment.day) import calendar unixtime = calendar.timegm(moment.timetuple()) unixtime = unixtime - unixtime % ( 86400 ) # Remove the remainder of the value, rounding it to the day it is transit, sunrise, sunset = spa.transit_sunrise_sunset(np.array([unixtime]), lat=latitude, lon=longitude, delta_t=delta_t, numthreads=1) transit = datetime.utcfromtimestamp(float(transit)) sunrise = datetime.utcfromtimestamp(float(sunrise)) sunset = datetime.utcfromtimestamp(float(sunset)) return sunrise, sunset, transit
def sunrise_sunset(moment, latitude, longitude): r'''Calculates the times at which the sun is at sunset; sunrise; and halfway between sunrise and sunset (transit). Uses the Reda and Andreas (2004) model described in [1]_, originally incorporated into the excellent `pvlib library <https://github.com/pvlib/pvlib-python>`_ Parameters ---------- moment : datetime Date for the calculation; needs to contain only the year, month, and day; if it is timezone-aware, the return values will be localized to this timezone [-] latitude : float Latitude, between -90 and 90 [degrees] longitude : float Longitude, between -180 and 180, [degrees] Returns ------- sunrise : datetime The time at the specified day when the sun rises **IN UTC IF MOMENT DOES NOT HAVE A TIMEZONE, OTHERWISE THE TIMEZONE GIVEN WITH IT**, [-] sunset : datetime The time at the specified day when the sun sets **IN UTC IF MOMENT DOES NOT HAVE A TIMEZONE, OTHERWISE THE TIMEZONE GIVEN WITH IT**, [-] transit : datetime The time at the specified day when the sun is at solar noon - halfway between sunrise and sunset **IN UTC IF MOMENT DOES NOT HAVE A TIMEZONE, OTHERWISE THE TIMEZONE GIVEN WITH IT**, [-] Examples -------- >>> sunrise, sunset, transit = sunrise_sunset(datetime(2018, 4, 17), ... 51.0486, -114.07) >>> sunrise datetime.datetime(2018, 4, 17, 12, 36, 55, 782660) >>> sunset datetime.datetime(2018, 4, 18, 2, 34, 4, 249326) >>> transit datetime.datetime(2018, 4, 17, 19, 35, 46, 686265) Example with time zone: >>> import pytz >>> sunrise_sunset(pytz.timezone('America/Edmonton').localize(datetime(2018, 4, 17)), 51.0486, -114.07) (datetime.datetime(2018, 4, 16, 6, 39, 1, 570479, tzinfo=<DstTzInfo 'America/Edmonton' MDT-1 day, 18:00:00 DST>), datetime.datetime(2018, 4, 16, 20, 32, 25, 778162, tzinfo=<DstTzInfo 'America/Edmonton' MDT-1 day, 18:00:00 DST>), datetime.datetime(2018, 4, 16, 13, 36, 0, 386341, tzinfo=<DstTzInfo 'America/Edmonton' MDT-1 day, 18:00:00 DST>)) Note that the year/month/day as input with a timezone, is converted to UTC time as well. Notes ----- This functions takes on the order of 2 ms per calculation. References ---------- .. [1] Reda, Ibrahim, and Afshin Andreas. "Solar Position Algorithm for Solar Radiation Applications." Solar Energy 76, no. 5 (January 1, 2004): 577-89. https://doi.org/10.1016/j.solener.2003.12.003. ''' from fluids.optional import spa import calendar if moment.utcoffset() is not None: moment_utc = moment + moment.utcoffset() else: moment_utc = moment delta_t = spa.calculate_deltat(moment_utc.year, moment_utc.month) # Strip the part of the day ymd_moment_utc = datetime(moment_utc.year, moment_utc.month, moment_utc.day) unixtime = calendar.timegm(ymd_moment_utc.utctimetuple()) unixtime = unixtime - unixtime % (86400) # Remove the remainder of the value, rounding it to the day it is transit, sunrise, sunset = spa.transit_sunrise_sunset(unixtime, lat=latitude, lon=longitude, delta_t=delta_t) transit = datetime.utcfromtimestamp(transit) sunrise = datetime.utcfromtimestamp(sunrise) sunset = datetime.utcfromtimestamp(sunset) if moment.tzinfo is not None: sunrise = moment.tzinfo.fromutc(sunrise) sunset = moment.tzinfo.fromutc(sunset) transit = moment.tzinfo.fromutc(transit) return sunrise, sunset, transit
def sunrise_sunset(moment, latitude, longitude): r'''Calculates the times at which the sun is at sunset; sunrise; and halfway between sunrise and sunset (transit). Uses the Reda and Andreas (2004) model described in [1]_, originally incorporated into the excellent `pvlib library <https://github.com/pvlib/pvlib-python>`_ Parameters ---------- moment : datetime Date for the calculationl; needs to contain only the year, month, and day, [-] latitude : float Latitude, between -90 and 90 [degrees] longitude : float Longitude, between -180 and 180, [degrees] Returns ------- sunrise : datetime The time at the specified day when the sun rises **IN UTC**, [-] sunset : datetime The time at the specified day when the sun sets **IN UTC**, [-] transit : datetime The time at the specified day when the sun is at solar noon - halfway between sunrise and sunset **IN UTC**, [-] Examples -------- >>> sunrise, sunset, transit = sunrise_sunset(datetime(2018, 4, 17), ... 51.0486, -114.07) >>> sunrise datetime.datetime(2018, 4, 17, 12, 36, 55, 782660) >>> sunset datetime.datetime(2018, 4, 18, 2, 34, 4, 249326) >>> transit datetime.datetime(2018, 4, 17, 19, 35, 46, 686265) Notes ----- This functions takes on the order of 2 ms per calculation. The reason the function cannot return the time correct the local timezone is that the function does not know the timezone at the specified lat/long. References ---------- .. [1] Reda, Ibrahim, and Afshin Andreas. "Solar Position Algorithm for Solar Radiation Applications." Solar Energy 76, no. 5 (January 1, 2004): 577-89. https://doi.org/10.1016/j.solener.2003.12.003. ''' from fluids.optional import spa delta_t = spa.calculate_deltat(moment.year, moment.month) # Strip the part of the day moment = datetime(moment.year, moment.month, moment.day) import calendar unixtime = calendar.timegm(moment.timetuple()) unixtime = unixtime - unixtime % (86400) # Remove the remainder of the value, rounding it to the day it is transit, sunrise, sunset = spa.transit_sunrise_sunset(np.array([unixtime]), lat=latitude, lon=longitude, delta_t=delta_t, numthreads=1) transit = datetime.utcfromtimestamp(float(transit)) sunrise = datetime.utcfromtimestamp(float(sunrise)) sunset = datetime.utcfromtimestamp(float(sunset)) return sunrise, sunset, transit