def phase_hunt(sdate=DateTime.now()): """Find time of phases of the moon which surround the current date. Five phases are found, starting and ending with the new moons which bound the current lunation. """ if not hasattr(sdate, 'jdn'): sdate = DateTime.DateTimeFromJDN(sdate) adate = sdate + DateTime.RelativeDateTime(days=-45) k1 = floor( (adate.year + ((adate.month - 1) * (1.0 / 12.0)) - 1900) * 12.3685) nt1 = meanphase(adate, k1) adate = nt1 sdate = sdate.jdn while 1: adate = adate + c.synodic_month k2 = k1 + 1 nt2 = meanphase(adate, k2) if nt1 <= sdate < nt2: break nt1 = nt2 k1 = k2 phases = list( map(truephase, [k1, k1, k1, k1, k2], [0 / 4.0, 1 / 4.0, 2 / 4.0, 3 / 4.0, 0 / 4.0])) return phases
def __str__(self): if type(self.date) is int: d = DateTime.DateTimeFromJDN(self.date) else: d = self.date s = "%s for %s, %s (%%%.2f illuminated)" %\ (self.__class__, d.strftime(), self.phase_text, self.illuminated * 100) return s
def __init__(self, date=DateTime.now()): """MoonPhase constructor. Give me a date, as either a Julian Day Number or a DateTime object.""" if not isinstance(date, DateTime.DateTimeType): self.date = DateTime.DateTimeFromJDN(date) else: self.date = date self.__dict__.update(phase(self.date)) self.phase_text = phase_string(self.phase)
def truephase(k, tphase): """Given a K value used to determine the mean phase of the new moon, and a phase selector (0.0, 0.25, 0.5, 0.75), obtain the true, corrected phase time.""" apcor = False # add phase to new moon time k = k + tphase # Time in Julian centuries from 1900 January 0.5 t = k / 1236.85 t2 = t * t t3 = t2 * t # Mean time of phase pt = (2415020.75933 + c.synodic_month * k + 0.0001178 * t2 - 0.000000155 * t3 + 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2)) # Sun's mean anomaly m = 359.2242 + 29.10535608 * k - 0.0000333 * t2 - 0.00000347 * t3 # Moon's mean anomaly mprime = 306.0253 + 385.81691806 * k + 0.0107306 * t2 + 0.00001236 * t3 # Moon's argument of latitude f = 21.2964 + 390.67050646 * k - 0.0016528 * t2 - 0.00000239 * t3 if (tphase < 0.01) or (abs(tphase - 0.5) < 0.01): # Corrections for New and Full Moon pt = pt + ( (0.1734 - 0.000393 * t) * dsin(m) + 0.0021 * dsin(2 * m) - 0.4068 * dsin(mprime) + 0.0161 * dsin(2 * mprime) - 0.0004 * dsin(3 * mprime) + 0.0104 * dsin(2 * f) - 0.0051 * dsin(m + mprime) - 0.0074 * dsin(m - mprime) + 0.0004 * dsin(2 * f + m) - 0.0004 * dsin(2 * f - m) - 0.0006 * dsin(2 * f + mprime) + 0.0010 * dsin(2 * f - mprime) + 0.0005 * dsin(m + 2 * mprime)) apcor = True elif (abs(tphase - 0.25) < 0.01) or (abs(tphase - 0.75) < 0.01): pt = pt + ( (0.1721 - 0.0004 * t) * dsin(m) + 0.0021 * dsin(2 * m) - 0.6280 * dsin(mprime) + 0.0089 * dsin(2 * mprime) - 0.0004 * dsin(3 * mprime) + 0.0079 * dsin(2 * f) - 0.0119 * dsin(m + mprime) - 0.0047 * dsin(m - mprime) + 0.0003 * dsin(2 * f + m) - 0.0004 * dsin(2 * f - m) - 0.0006 * dsin(2 * f + mprime) + 0.0021 * dsin(2 * f - mprime) + 0.0003 * dsin(m + 2 * mprime) + 0.0004 * dsin(m - 2 * mprime) - 0.0003 * dsin(2 * m + mprime)) if (tphase < 0.5): # First quarter correction pt = pt + 0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime) else: # Last quarter correction pt = pt + -0.0028 + 0.0004 * dcos(m) - 0.0003 * dcos(mprime) apcor = True if not apcor: raise ValueError("TRUEPHASE called with invalid phase selector", tphase) return DateTime.DateTimeFromJDN(pt)