Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate "Solar Noon" using ephem, translating to local time

I have looked at the examples here on using ephem to calculate sunrise and sunset, and have that working great.

I get in trouble when I try to calculate the midpoint between those two times. Here's what I have:

import datetime
import ephem

o = ephem.Observer()
o.lat, o.long, o.date = '37.0625', '-95.677068', datetime.datetime.utcnow()
sun = ephem.Sun(o)
print "sunrise:", o.previous_rising(sun), "UTC"
print "sunset:",o.next_setting(sun), "UTC"
print "noon:",datetime.timedelta((o.next_setting(sun)-o.previous_rising(sun))/2)

I get:

sunrise: 2010/11/2 12:47:40 UTC
sunset: 2010/11/2 23:24:25 UTC
noon: 5:18:22.679044

That's where I'm stuck. I'm a python beginner and frankly not much of a programmer in general.

Any suggestions would be most welcome!

like image 646
Lorin Rivers Avatar asked Nov 02 '10 22:11

Lorin Rivers


People also ask

How do you calculate solar noon?

(60 minutes / 15 degrees = 4 minutes per degree.). So to calculate solar noon where you live just figure out how many degrees you are west from the last time zone starting point and add 4 minutes for each degree you are away from it! You know that the Time Zones are at set degrees (0, 15, 30, 45 ect.)

How is solar day length calculated?

cos(ω) = − tan(δ) tan(δ) = −1, which gives ω = 180◦ ⇒ sunrise = midnight. So the sun rises, at exactly the time it sets. There are 24 hours of daylight with the sun just dipping below the horizon at precisely midnight.

How do you calculate sunrise?

Sunrise/Sunset Calculations where the positive number corresponds to sunrise, negative to sunset. Then the UTC time of sunrise (or sunset) in minutes is: sunrise = 720 – 4*(longitude + ha) – eqtime where longitude and hour angle are in degrees and the equation of time is in minutes.


2 Answers

Solar noon is not the mean of sunrise and sunset (see equation of time for the explanation). The ephem package has methods for getting transit times which you should use instead:

>>> import ephem
>>> o = ephem.Observer()
>>> o.lat, o.long = '37.0625', '-95.677068'
>>> sun = ephem.Sun()
>>> sunrise = o.previous_rising(sun, start=ephem.now())
>>> noon = o.next_transit(sun, start=sunrise)
>>> sunset = o.next_setting(sun, start=noon)
>>> noon
2010/11/6 18:06:21
>>> ephem.date((sunrise + sunset) / 2)
2010/11/6 18:06:08

Note that noon today is 13 seconds later (at your location) than the mean of sunrise and sunset.

(The line of code ephem.date((sunrise + sunset) / 2) shows how you could easily manipulate dates in the ephem package, if it were the right thing to do.)

like image 158
Gareth Rees Avatar answered Nov 07 '22 04:11

Gareth Rees


If using ephem is not a hard requirement, I recently wrote a library called daylight which has a native function for solar noon directly.

>>> import daylight, pytz
>>> from datetime import datetime
>>> sun = daylight.Sunclock(37.0625, -95.677068)
>>> t = sun.solar_noon(datetime.utcnow().timestamp())
>>> datetime.utcfromtimestamp(t)
datetime.datetime(2020, 6, 4, 18, 20, 54)

Not that above time is in UTC. For a more appropriate timezone, say EST, you can do:

>>> tz = pytz.timezone('EST')
>>> tz_offset = tz.utcoffset(datetime.utcnow()).total_seconds()/3600
>>> sun = daylight.Sunclock(37.0625, -95.677068, tz_offset)
>>> t = sun.solar_noon(datetime.utcnow().timestamp())
>>> datetime.utcfromtimestamp(t).astimezone(tz)
datetime.datetime(2020, 6, 3, 7, 50, 54, tzinfo=<StaticTzInfo 'EST'>)

or do this for a particular date, say May 21st 2020

>>> t = sun.solar_noon(datetime(2020, 5, 21).timestamp())
>>> datetime.utcfromtimestamp(t)
datetime.datetime(2020, 5, 20, 18, 19, 14)
like image 28
chaitan94 Avatar answered Nov 07 '22 05:11

chaitan94