def new_moon_before(cls, tee): """Return the approximate moment of last new moon preceding moment, tee, close enough to determine zodiacal sign.""" varepsilon = pow(2, -1000) tau = tee - ((1/360) * cls.lunar_phase(tee) * cls.SYNODIC_MONTH) return binary_search(tau - 1, min(tee, tau + 1), lambda l, u: cls.zodiac(l) == cls.zodiac(u) or u - l < varepsilon, lambda x: cls.lunar_phase(x) < 180)
def moonrise(self, date): """Return the standard time of moonrise on fixed, date, and location, location.""" t = self.universal_from_standard(date) waning = (Lunar.lunar_phase(t) > 180) alt = self.observed_lunar_altitude(t) offset = alt / 360 if waning and (offset > 0): approx = t + 1 - offset elif waning: approx = t - offset else: approx = t + (1 / 2) + offset rise = binary_search(approx - Clock.days_from_hours(3), approx + Clock.days_from_hours(3), lambda u, l: ((u - l) < Clock.days_from_hours(1/60)), lambda x: self.observed_lunar_altitude(x) > 0) if rise < (t + 1): return self.standard_from_universal(rise) raise ValueError()