Skip to content

Instantly share code, notes, and snippets.

@tkanmae
Last active December 20, 2015 03:28
Show Gist options
  • Save tkanmae/6063324 to your computer and use it in GitHub Desktop.
Save tkanmae/6063324 to your computer and use it in GitHub Desktop.
Display a table of rising and setting times of the Sun and Moon.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
import argparse
import datetime
import calendar
import ephem
CITIES = {
# Fairbanks, AK
'Fairbanks, AK': {
'latitude': 64.8377800,
'longitude': -147.7163900,
'elevation': 0,
},
# Broomfield, CO
'Broomfield, CO': {
'latitude': 39.9008,
'longitude': -105.1042,
'elevation': 1724
},
}
def days_in_month(year, month):
"""Return the number of days in a given month and year."""
return calendar.monthrange(year, month)[1]
def as_datetime(date, localtime=False):
"""Return a `datetime.datetime` object for a given `ephem.Date` object."""
if date is None:
return None
if localtime:
return ephem.localtime(date)
else:
return date.datetime()
def city(name):
try:
return ephem.city(name)
except KeyError:
pass
data = CITIES[name]
o = ephem.Observer()
o.name = name
o.lat, o.lon = str(data['latitude']), str(data['longitude'])
o.elevation = data['elevation']
o.compute_pressure()
return o
def print_header(o, localtime):
print('{0.name} Lat={0.lat} Lon={0.lon} '
'Elv={0.elevation} m'.format(o))
date = o.date.datetime().strftime('%B, %Y')
if localtime:
print('{0} (time in local time)'.format(date))
else:
print('{0} (time in UTC)'.format(date))
print('')
def print_table(data):
def print_entry(day, x):
y = {}
for key in ('sun_rise_time', 'sun_set_time', 'moon_rise_time',
'moon_set_time'):
y[key] = x[key].strftime('%H:%M:%S') if x[key] else 8 * '-'
y.update({'moon_phase': x['moon_phase']})
print(' {0:02d} {1[moon_phase]:3.0f} '
'{1[moon_rise_time]} {1[moon_set_time]} '
'{1[sun_rise_time]} {1[sun_set_time]}'.format(day, y))
print(' Moon Sun')
print('Date % Rise Set Rise Set')
for day, x in enumerate(data, 1):
print_entry(day, x)
def compute(city_name, year, month, refract=False, localtime=False):
o = city(city_name)
s = ephem.Sun()
m = ephem.Moon()
if not refract:
o.pressure = 0
num_days = days_in_month(year, month)
data = []
for day in range(1, num_days + 1):
o.date = '{0}/{1}/{2}'.format(year, month, day)
s.compute(o)
m.compute(o)
data.append({
'sun_rise_time': as_datetime(s.rise_time, localtime),
'sun_set_time': as_datetime(s.set_time, localtime),
'moon_rise_time': as_datetime(m.rise_time, localtime),
'moon_set_time': as_datetime(m.set_time, localtime),
'moon_phase': m.phase,
})
if localtime:
moon_rise_times = [None for i in range(num_days)]
for x in (_['moon_rise_time'] for _ in data):
if x:
moon_rise_times[x.day - 1] = x
moon_set_times = [None for i in range(num_days)]
for x in (_['moon_set_time'] for _ in data):
if x:
moon_set_times[x.day - 1] = x
for i, (rise_time, set_time) in enumerate(zip(moon_rise_times,
moon_set_times)):
data[i]['moon_rise_time'] = rise_time
data[i]['moon_set_time'] = set_time
print_header(o, localtime)
print_table(data)
def init_argparser():
parser = argparse.ArgumentParser(prog='smtable')
parser.add_argument('city', type=str,
help='display in local time')
parser.add_argument('-y', '--year', type=int,
help='year')
parser.add_argument('-m', '--month', type=int,
help='month')
parser.add_argument('-l', '--localtime', action='store_true',
help='display in local time')
help = 'include the effects of the atmospheric refraction'
parser.add_argument('-r', '--refract', action='store_true',
help=help)
return parser
def main(args):
now = datetime.datetime.utcnow()
city_name = args.city
localtime = args.localtime
year = args.year if args.year else now.year
month = args.month if args.month else now.month
compute(city_name, year, month, localtime=localtime)
if __name__ == '__main__':
parser = init_argparser()
main(parser.parse_args())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment