2023-11-27 17:21:11 +00:00
|
|
|
|
# sun_moon.py MicroPython Port of lunarmath.c
|
|
|
|
|
# Calculate sun and moon rise and set times for any date and location
|
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# Licensing and copyright: see README.md
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# Source "Astronomy on the Personal Computer" by Montenbruck and Pfleger
|
|
|
|
|
# ISBN 978-3-540-67221-0
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# Also contributions from Raul Kompaß and Marcus Mendenhall: see
|
|
|
|
|
# https://github.com/orgs/micropython/discussions/13075
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
from math import sin, cos, sqrt, fabs, atan, radians, floor
|
|
|
|
|
|
|
|
|
|
LAT = 53.29756504536339 # Local defaults
|
|
|
|
|
LONG = -2.102811634540558
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def quad(ym, yz, yp):
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# See Astronomy on the PC P48-49, plus contribution from Marcus Mendenhall
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# finds the parabola throuh the three points (-1,ym), (0,yz), (1, yp)
|
|
|
|
|
# and returns the values of x where the parabola crosses zero
|
|
|
|
|
# (roots of the quadratic)
|
|
|
|
|
# and the number of roots (0, 1 or 2) within the interval [-1, 1]
|
|
|
|
|
nz = 0
|
|
|
|
|
a = 0.5 * (ym + yp) - yz
|
|
|
|
|
b = 0.5 * (yp - ym)
|
|
|
|
|
c = yz
|
|
|
|
|
xe = -b / (2 * a)
|
|
|
|
|
ye = (a * xe + b) * xe + c
|
|
|
|
|
dis = b * b - 4.0 * a * c # discriminant of y=a*x^2 +bx +c
|
|
|
|
|
if dis > 0: # parabola has roots
|
2023-11-29 12:13:28 +00:00
|
|
|
|
if b < 0:
|
|
|
|
|
z2 = (-b + sqrt(dis)) / (2 * a) # z2 is larger root in magnitude
|
|
|
|
|
else:
|
|
|
|
|
z2 = (-b - sqrt(dis)) / (2 * a)
|
|
|
|
|
z1 = (c / a) / z2 # z1 is always closer to zero
|
2023-11-27 17:21:11 +00:00
|
|
|
|
if fabs(z1) <= 1.0:
|
|
|
|
|
nz += 1
|
|
|
|
|
if fabs(z2) <= 1.0:
|
|
|
|
|
nz += 1
|
|
|
|
|
if z1 < -1.0:
|
|
|
|
|
z1 = z2
|
|
|
|
|
return nz, z1, z2, ye
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# **** GET MODIFIED JULIAN DATE FOR DAY RELATIVE TO TODAY ****
|
|
|
|
|
|
|
|
|
|
# Takes the system time in seconds from 1 Jan 70 & returns
|
|
|
|
|
# modified julian day number defined as mjd = jd - 2400000.5
|
|
|
|
|
# Deals only in integer MJD's: the JD of just after midnight will always end in 0.5
|
|
|
|
|
# hence the MJD of an integer day number will always be an integer
|
|
|
|
|
|
|
|
|
|
# MicroPython wanton epochs:
|
|
|
|
|
# time.gmtime(0)[0] = 1970 or 2000 depending on platform.
|
|
|
|
|
# (date(2000, 1, 1) - date(1970, 1, 1)).days * 24*60*60 = 946684800
|
|
|
|
|
# (date(2000, 1, 1) - date(1970, 1, 1)).days = 10957
|
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# Re platform comparisons get_mjd returns the same value regardless of
|
|
|
|
|
# the platform's epoch: integer days since 00:00 on 17 November 1858.
|
2023-11-27 17:21:11 +00:00
|
|
|
|
def get_mjd(ndays: int = 0) -> int: # Days offset from today
|
|
|
|
|
secs_per_day = 86400 # 24 * 3600
|
|
|
|
|
tsecs = time.time() # Time now in secs since epoch
|
|
|
|
|
tsecs -= tsecs % secs_per_day # Time last midnight
|
|
|
|
|
tsecs += secs_per_day * ndays # Specified day
|
|
|
|
|
days_from_epoch = round(tsecs / secs_per_day) # Days from 1 Jan 70
|
|
|
|
|
# tsecs += secs_per_day # 2 # Noon
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# mjepoch = -10957.5 # 40587 - 51544.5 # Modified Julian date of C epoch (1 Jan 70)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
mjepoch = 40587 # Modified Julian date of C epoch (1 Jan 70)
|
|
|
|
|
if time.gmtime(0)[0] == 2000:
|
|
|
|
|
mjepoch += 10957
|
|
|
|
|
return mjepoch + days_from_epoch # Convert days from 1 Jan 70 to MJD
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def frac(x):
|
|
|
|
|
return x % 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Convert rise or set time to int. These can be None (no event).
|
|
|
|
|
def to_int(x):
|
|
|
|
|
return None if x is None else round(x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Approximate moon phase in range 0.0..1.0 0.0 is new moon, 0.5 full moon
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# Provenance of this cde is uncertain.
|
2023-11-27 17:21:11 +00:00
|
|
|
|
def moonphase(year, month, day, hour):
|
|
|
|
|
fty = year - floor((12.0 - month) / 10.0)
|
|
|
|
|
itm = month + 9
|
|
|
|
|
if itm >= 12:
|
|
|
|
|
itm -= 12
|
|
|
|
|
term1 = floor(365.25 * (fty + 4712))
|
|
|
|
|
term2 = floor(30.6 * itm + 0.5)
|
|
|
|
|
term3 = floor(floor((fty / 100) + 49) * 0.75) - 38
|
|
|
|
|
tmp = term1 + term2 + day + 59 + hour / 24.0
|
|
|
|
|
if tmp > 2299160.0:
|
|
|
|
|
tmp = tmp - term3
|
2023-11-29 12:13:28 +00:00
|
|
|
|
phi = (tmp - 2451550.1) / 29.530588853 # 29.530588853 is length of lunar cycle (days)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
return phi % 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def minisun(t):
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# Output sin(dec), cos(dec), ra
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# returns the ra and dec of the Sun
|
|
|
|
|
# in decimal hours, degs referred to the equinox of date and using
|
|
|
|
|
# obliquity of the ecliptic at J2000.0 (small error for +- 100 yrs)
|
|
|
|
|
# takes t centuries since J2000.0. Claimed good to 1 arcmin
|
|
|
|
|
p2 = 6.283185307
|
|
|
|
|
coseps = 0.91748
|
|
|
|
|
sineps = 0.39778
|
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
m = p2 * frac(0.993133 + 99.997361 * t)
|
|
|
|
|
dl = 6893.0 * sin(m) + 72.0 * sin(2 * m)
|
|
|
|
|
l = p2 * frac(0.7859453 + m / p2 + (6191.2 * t + dl) / 1296000)
|
|
|
|
|
sl = sin(l)
|
|
|
|
|
x = cos(l)
|
|
|
|
|
y = coseps * sl
|
|
|
|
|
z = sineps * sl
|
|
|
|
|
rho = sqrt(1 - z * z)
|
|
|
|
|
# dec = (360.0 / p2) * atan(z / rho)
|
|
|
|
|
ra = (48.0 / p2) * atan(y / (x + rho)) % 24
|
|
|
|
|
return z, rho, ra
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def minimoon(t):
|
|
|
|
|
# takes t and returns the geocentric ra and dec
|
|
|
|
|
# claimed good to 5' (angle) in ra and 1' in dec
|
|
|
|
|
# tallies with another approximate method and with ICE for a couple of dates
|
|
|
|
|
|
|
|
|
|
p2 = 6.283185307
|
|
|
|
|
arc = 206264.8062
|
|
|
|
|
coseps = 0.91748
|
|
|
|
|
sineps = 0.39778
|
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
l0 = frac(0.606433 + 1336.855225 * t) # mean longitude of moon
|
|
|
|
|
l = p2 * frac(0.374897 + 1325.552410 * t) # mean anomaly of Moon
|
|
|
|
|
ls = p2 * frac(0.993133 + 99.997361 * t) # mean anomaly of Sun
|
|
|
|
|
d = p2 * frac(0.827361 + 1236.853086 * t) # difference in longitude of moon and sun
|
|
|
|
|
f = p2 * frac(0.259086 + 1342.227825 * t) # mean argument of latitude
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# corrections to mean longitude in arcsec
|
2023-11-30 15:44:14 +00:00
|
|
|
|
dl = 22640 * sin(l)
|
|
|
|
|
dl += -4586 * sin(l - 2 * d)
|
|
|
|
|
dl += +2370 * sin(2 * d)
|
|
|
|
|
dl += +769 * sin(2 * l)
|
|
|
|
|
dl += -668 * sin(ls)
|
|
|
|
|
dl += -412 * sin(2 * f)
|
|
|
|
|
dl += -212 * sin(2 * l - 2 * d)
|
|
|
|
|
dl += -206 * sin(l + ls - 2 * d)
|
|
|
|
|
dl += +192 * sin(l + 2 * d)
|
|
|
|
|
dl += -165 * sin(ls - 2 * d)
|
|
|
|
|
dl += -125 * sin(d)
|
|
|
|
|
dl += -110 * sin(l + ls)
|
|
|
|
|
dl += +148 * sin(l - ls)
|
|
|
|
|
dl += -55 * sin(2 * f - 2 * d)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# simplified form of the latitude terms
|
2023-11-30 15:44:14 +00:00
|
|
|
|
s = f + (dl + 412 * sin(2 * f) + 541 * sin(ls)) / arc
|
|
|
|
|
h = f - 2 * d
|
|
|
|
|
n = -526 * sin(h)
|
|
|
|
|
n += +44 * sin(l + h)
|
|
|
|
|
n += -31 * sin(-l + h)
|
|
|
|
|
n += -23 * sin(ls + h)
|
|
|
|
|
n += +11 * sin(-ls + h)
|
|
|
|
|
n += -25 * sin(-2 * l + f)
|
|
|
|
|
n += +21 * sin(-l + f)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# ecliptic long and lat of Moon in rads
|
2023-11-30 15:44:14 +00:00
|
|
|
|
l_moon = p2 * frac(l0 + dl / 1296000)
|
|
|
|
|
b_moon = (18520.0 * sin(s) + n) / arc
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# equatorial coord conversion - note fixed obliquity
|
2023-11-30 15:44:14 +00:00
|
|
|
|
cb = cos(b_moon)
|
|
|
|
|
x = cb * cos(l_moon)
|
|
|
|
|
v = cb * sin(l_moon)
|
|
|
|
|
W = sin(b_moon)
|
|
|
|
|
y = coseps * v - sineps * W
|
|
|
|
|
z = sineps * v + coseps * W
|
|
|
|
|
rho = sqrt(1.0 - z * z)
|
|
|
|
|
# dec = (360.0 / p2) * atan(z / rho)
|
|
|
|
|
ra = (48.0 / p2) * atan(y / (x + rho)) % 24
|
|
|
|
|
return z, rho, ra
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RiSet:
|
2023-11-29 12:13:28 +00:00
|
|
|
|
def __init__(self, lat=LAT, long=LONG, lto=0): # Local defaults
|
2023-11-27 17:21:11 +00:00
|
|
|
|
self.sglat = sin(radians(lat))
|
|
|
|
|
self.cglat = cos(radians(lat))
|
|
|
|
|
self.long = long
|
2023-11-29 12:13:28 +00:00
|
|
|
|
self.lto = round(lto * 3600) # Localtime offset in secs
|
2023-11-27 17:21:11 +00:00
|
|
|
|
self.mjd = None # Current integer MJD
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# Times in integer secs from midnight on current day (in local time)
|
|
|
|
|
# [sunrise, sunset, moonrise, moonset]
|
|
|
|
|
self._times = [None] * 4
|
2023-11-27 17:21:11 +00:00
|
|
|
|
self.set_day() # Initialise to today's date
|
|
|
|
|
|
|
|
|
|
# ***** API start *****
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# Examine Julian dates either side of current one to cope with localtime.
|
|
|
|
|
# TODO: Allow localtime offset to be varied at runtime for DST.
|
|
|
|
|
# TODO: relative=True arg for set_day. Allows entering absolute dates e.g. for testing.
|
|
|
|
|
def set_day(self, day: int = 0, relative: bool = True):
|
2023-11-27 17:21:11 +00:00
|
|
|
|
mjd = get_mjd(day)
|
|
|
|
|
if self.mjd is None or self.mjd != mjd:
|
|
|
|
|
spd = 86400 # Secs per day
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# ._t0 is time of midnight (local time) in secs since MicroPython epoch
|
|
|
|
|
# time.time() assumes MicroPython clock is set to local time
|
|
|
|
|
self._t0 = ((round(time.time()) + day * spd) // spd) * spd
|
|
|
|
|
t = time.gmtime(time.time() + day * spd)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
self._phase = moonphase(*t[:4])
|
2023-11-30 15:44:14 +00:00
|
|
|
|
self.update(mjd) # Recalculate rise and set times
|
2023-11-29 12:13:28 +00:00
|
|
|
|
return self # Allow r.set_day().sunrise()
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# variants: 0 secs since 00:00:00 localtime. 1 secs since MicroPython epoch
|
|
|
|
|
# (relies on system being set to localtime). 2 human-readable text.
|
|
|
|
|
def sunrise(self, variant: int = 0):
|
|
|
|
|
return self._format(self._times[0], variant)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
def sunset(self, variant: int = 0):
|
|
|
|
|
return self._format(self._times[1], variant)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
def moonrise(self, variant: int = 0):
|
|
|
|
|
return self._format(self._times[2], variant)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
def moonset(self, variant: int = 0):
|
|
|
|
|
return self._format(self._times[3], variant)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
def moonphase(self) -> float:
|
2023-11-27 17:21:11 +00:00
|
|
|
|
return self._phase
|
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
def set_lto(self, t): # Update the offset from UTC
|
|
|
|
|
pass # TODO
|
|
|
|
|
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# ***** API end *****
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# Re-calculate rise and set times
|
|
|
|
|
def update(self, mjd):
|
|
|
|
|
self._times = [None] * 4
|
|
|
|
|
days = (1, 2) if self.lto < 0 else (1,) if self.lto == 0 else (0, 1)
|
|
|
|
|
for day in days:
|
|
|
|
|
self.mjd = mjd + day - 1
|
|
|
|
|
sr, ss = self.rise_set(True) # Sun
|
|
|
|
|
mr, ms = self.rise_set(False) # Moon
|
|
|
|
|
# Adjust for local time. Store in ._times if value is in 24-hour
|
|
|
|
|
# local time window
|
|
|
|
|
self.adjust(sr, day, 0)
|
|
|
|
|
self.adjust(ss, day, 1)
|
|
|
|
|
self.adjust(mr, day, 2)
|
|
|
|
|
self.adjust(ms, day, 3)
|
|
|
|
|
self.mjd = mjd
|
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
def adjust(self, n, day, idx):
|
|
|
|
|
if n is not None:
|
|
|
|
|
n += self.lto + (day - 1) * 86400
|
|
|
|
|
h = n // 3600
|
|
|
|
|
if 0 <= h < 24:
|
|
|
|
|
self._times[idx] = n
|
|
|
|
|
|
|
|
|
|
def _format(self, n, variant):
|
|
|
|
|
if variant == 0: # Default: secs since Midnight (local time)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
return n
|
2023-11-29 12:13:28 +00:00
|
|
|
|
elif variant == 1: # Secs since epoch of MicroPython platform
|
2023-11-27 17:21:11 +00:00
|
|
|
|
return None if n is None else n + self._t0
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# variant == 3
|
2023-11-27 17:21:11 +00:00
|
|
|
|
if n is None:
|
|
|
|
|
return "--:--:--"
|
|
|
|
|
else:
|
|
|
|
|
hr, tmp = divmod(n, 3600)
|
|
|
|
|
mi, sec = divmod(tmp, 60)
|
|
|
|
|
return f"{hr:02d}:{mi:02d}:{sec:02d}"
|
|
|
|
|
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# See https://github.com/orgs/micropython/discussions/13075
|
2023-11-30 15:44:14 +00:00
|
|
|
|
def lmst(self, t):
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# Takes the mjd and the longitude (west negative) and then returns
|
|
|
|
|
# the local sidereal time in hours. Im using Meeus formula 11.4
|
|
|
|
|
# instead of messing about with UTo and so on
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# modified to use the pre-computed 't' value from sin_alt
|
|
|
|
|
d = t * 36525
|
|
|
|
|
df = frac(d)
|
|
|
|
|
c1 = 360
|
|
|
|
|
c2 = 0.98564736629
|
|
|
|
|
dsum = c1 * df + c2 * d # no large integer * 360 here
|
|
|
|
|
lst = 280.46061837 + dsum + 0.000387933 * t * t - t * t * t / 38710000
|
2023-11-27 17:21:11 +00:00
|
|
|
|
return (lst % 360) / 15.0 + self.long / 15
|
|
|
|
|
|
|
|
|
|
def sin_alt(self, hour, func):
|
|
|
|
|
# Returns the sine of the altitude of the object (moon or sun)
|
|
|
|
|
# at an hour relative to the current date (mjd)
|
2023-11-29 12:13:28 +00:00
|
|
|
|
mjd1 = (self.mjd - 51544.5) + hour / 24.0
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# mjd1 = self.mjd + hour / 24.0
|
2023-11-29 12:13:28 +00:00
|
|
|
|
t1 = mjd1 / 36525.0
|
2023-11-30 15:44:14 +00:00
|
|
|
|
sin_dec, cos_dec, ra = func(t1)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# hour angle of object: one hour = 15 degrees. Note lmst() uses longitude
|
2023-11-30 15:44:14 +00:00
|
|
|
|
tau = 15.0 * (self.lmst(t1) - ra)
|
2023-11-27 17:21:11 +00:00
|
|
|
|
# sin(alt) of object using the conversion formulas
|
2023-11-30 15:44:14 +00:00
|
|
|
|
return self.sglat * sin_dec + self.cglat * cos_dec * cos(radians(tau))
|
2023-11-27 17:21:11 +00:00
|
|
|
|
|
|
|
|
|
# Modified to find sunrise and sunset only, not twilight events.
|
|
|
|
|
def rise_set(self, sun):
|
|
|
|
|
# this is my attempt to encapsulate most of the program in a function
|
|
|
|
|
# then this function can be generalised to find all the Sun events.
|
|
|
|
|
t_rise = None # Rise and set times in secs from midnight
|
|
|
|
|
t_set = None
|
|
|
|
|
sinho = sin(radians(-0.833)) if sun else sin(radians(8 / 60))
|
|
|
|
|
# moonrise taken as centre of moon at +8 arcmin
|
|
|
|
|
# sunset upper limb simple refraction
|
|
|
|
|
# The loop finds the sin(alt) for sets of three consecutive
|
|
|
|
|
# hours, and then tests for a single zero crossing in the interval
|
|
|
|
|
# or for two zero crossings in an interval for for a grazing event
|
|
|
|
|
func = minisun if sun else minimoon
|
|
|
|
|
yp = self.sin_alt(0, func) - sinho
|
|
|
|
|
for hour in range(1, 24, 2):
|
|
|
|
|
ym = yp
|
|
|
|
|
yz = self.sin_alt(hour, func) - sinho
|
|
|
|
|
yp = self.sin_alt(hour + 1, func) - sinho
|
|
|
|
|
nz, z1, z2, ye = quad(ym, yz, yp) # Find horizon crossings
|
|
|
|
|
if nz == 1: # One crossing found
|
|
|
|
|
if ym < 0.0:
|
|
|
|
|
t_rise = 3600 * (hour + z1)
|
|
|
|
|
else:
|
|
|
|
|
t_set = 3600 * (hour + z1)
|
|
|
|
|
# case where two events are found in this interval
|
|
|
|
|
# (rare but whole reason we are not using simple iteration)
|
|
|
|
|
elif nz == 2:
|
|
|
|
|
if ye < 0.0:
|
|
|
|
|
t_rise = 3600 * (hour + z2)
|
|
|
|
|
t_set = 3600 * (hour + z1)
|
|
|
|
|
else:
|
|
|
|
|
t_rise = 3600 * (hour + z1)
|
|
|
|
|
t_set = 3600 * (hour + z2)
|
|
|
|
|
|
|
|
|
|
if t_rise is not None and t_set is not None:
|
|
|
|
|
break # All done
|
|
|
|
|
return to_int(t_rise), to_int(t_set) # Convert to int preserving None values
|
|
|
|
|
|
|
|
|
|
|
2023-11-30 15:44:14 +00:00
|
|
|
|
# r = RiSet()
|
|
|
|
|
# r = RiSet(lat=47.61, long=-122.35, lto=-8) # Seattle 47°36′35″N 122°19′59″W
|
|
|
|
|
r = RiSet(lat=-33.86, long=151.21, lto=11) # Sydney 33°52′04″S 151°12′36″E
|
2023-11-29 12:13:28 +00:00
|
|
|
|
# t = time.ticks_us()
|
|
|
|
|
# r.set_day()
|
|
|
|
|
# print("Elapsed us", time.ticks_diff(time.ticks_us(), t))
|
2023-11-27 17:21:11 +00:00
|
|
|
|
for d in range(7):
|
|
|
|
|
print(f"Day {d}")
|
|
|
|
|
r.set_day(d)
|
|
|
|
|
print(f"Sun rise {r.sunrise(3)} set {r.sunset(3)}")
|
|
|
|
|
print(f"Moon rise {r.moonrise(3)} set {r.moonset(3)}")
|
2023-11-29 12:13:28 +00:00
|
|
|
|
|
|
|
|
|
print(r.set_day().sunrise(0))
|
|
|
|
|
# for d in range(30):
|
|
|
|
|
# r.set_day(d)
|
|
|
|
|
# print(round(r.moonphase() * 1000))
|