Last active
December 20, 2015 03:28
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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