def location(cls, tee): """Return location of Beijing; time zone varies with time, tee.""" year = GregorianDate.to_year(ifloor(tee)) if (year < 1929): return Location(angle(39, 55, 0), angle(116, 25, 0), 43.5, Clock.days_from_hours(1397/180)) else: return Location(angle(39, 55, 0), angle(116, 25, 0), 43.5, Clock.days_from_hours(8))
def vietnamese_location(tee): """Return the location for Vietnamese calendar is Hanoi; varies with moment, tee. Time zone has changed over the years.""" if (tee < GregorianDate.new_year(1968)): z = 8 else: z =7 return Location(angle(21, 2, 0), angle(105, 51, 0), 12, Clock.days_from_hours(z))
def obliquity(cls, tee): """Return (mean) obliquity of ecliptic at moment tee.""" c = cls.julian_centuries(tee) return (angle(23, 26, mpf(21.448)) + poly(c, [mpf(0), angle(0, 0, mpf(-46.8150)), angle(0, 0, mpf(-0.00059)), angle(0, 0, mpf(0.001813))]))
def korean_location(tee): """Return the location for Korean calendar; varies with moment, tee.""" # Seoul city hall at a varying time zone. if (tee < GregorianDate(1908, MonthOfYear.April, 1).to_fixed()): #local mean time for longitude 126 deg 58 min z = 3809/450 elif (tee < GregorianDate(1912, MonthOfYear.January, 1).to_fixed()): z = 8.5 elif (tee < GregorianDate(1954, MonthOfYear.March, 21).to_fixed()): z = 9 elif (tee < GregorianDate(1961, MonthOfYear.August, 10).to_fixed()): z = 8.5 else: z = 9 return Location(angle(37, 34, 0), angle(126, 58, 0), 0, Clock.days_from_hours(z))
def arcsin(cls, amp): """Return the inverse of Hindu sine function of amp.""" if (amp < 0): return -cls.arcsin(-amp) else: pos = next_int(0, lambda k: amp <= cls.sine_table(k)) below = cls.sine_table(pos - 1) return (angle(0, 225, 0) * (pos - 1 + ((amp - below) / (cls.sine_table(pos) - below))))
def daily_motion(cls, date): """Return the sidereal daily motion of sun on date, date.""" mean_motion = 360 / cls.SIDEREAL_YEAR anomaly = cls.mean_position(date, cls.ANOMALISTIC_YEAR) epicycle = 14/360 - abs(cls.sine(anomaly)) / 1080 entry = quotient(float(anomaly), angle(0, 225, 0)) sine_table_step = cls.sine_table(entry + 1) - cls.sine_table(entry) factor = -3438/225 * sine_table_step * epicycle return mean_motion * (factor + 1)
def japanese_location(tee): """Return the location for Japanese calendar; varies with moment, tee.""" year = GregorianDate.to_year(ifloor(tee)) if (year < 1888): # Tokyo (139 deg 46 min east) local time loc = Location(mpf(35.7), angle(139, 46, 0), 24, Clock.days_from_hours(9 + 143/450)) else: # Longitude 135 time zone loc = Location(35, 135, 0, Clock.days_from_hours(9)) return loc
def refraction(self, tee): """Return refraction angle at location 'location' and time 'tee'.""" h = max(0, self.elevation) cap_R = 6.372E6 dip = arccos_degrees(cap_R / (cap_R + h)) return angle(0, 50, 0) + dip + secs(19) * math.sqrt(h)
ignoring parallax and refraction. Adapted from 'Astronomical Algorithms' by Jean Meeus, Willmann_Bell, Inc., 1998.""" lamb = Lunar.lunar_longitude(tee) beta = Lunar.lunar_latitude(tee) alpha = Astro.right_ascension(tee, beta, lamb) delta = Astro.declination(tee, beta, lamb) theta0 = Astro.sidereal_from_moment(tee) cap_H = mod(theta0 + self.longitude - alpha, 360) altitude = arcsin_degrees( (sin_degrees(self.latitude) * sin_degrees(delta)) + (cos_degrees(self.latitude) * cos_degrees(delta) * cos_degrees(cap_H))) return mod(altitude + 180, 360) - 180 def visible_crescent(self, date): """Return S. K. Shaukat's criterion for likely visibility of crescent moon on eve of date 'date', at location 'location'.""" tee = self.universal_from_standard(self.dusk(date - 1, mpf(4.5))) phase = Lunar.lunar_phase(tee) altitude = self.lunar_altitude(tee) arc_of_light = arccos_degrees(cos_degrees(Lunar.lunar_latitude(tee)) * cos_degrees(phase)) return ((Lunar.NEW < phase < Lunar.FIRST_QUARTER) and (mpf(10.6) <= arc_of_light <= 90) and (altitude > mpf(4.1))) MECCA = Location(angle(21, 25, 24), angle(39, 49, 24), 298, Clock.days_from_hours(3)) JERUSALEM = Location(31.8, 35.2, 800, Clock.days_from_hours(2)) BRUXELLES = Location(angle(4, 21, 17), angle(50, 50, 47), 800, Clock.days_from_hours(1)) URBANA = Location(40.1, -88.2, 225, Clock.days_from_hours(-6)) GREENWHICH = Location(51.4777815, 0, 46.9, Clock.days_from_hours(0))
def yoga(date): """Return the Hindu yoga on date, date.""" return ifloor(mod((HinduSolarDate.longitude(date) + HinduLunarDate.longitude(date)) / angle(0, 800, 0), 27)) + 1
def hindu_lunar_station(date): """Return the Hindu lunar station (nakshatra) at sunrise on date, date.""" critical = HinduDate.sunrise(date) return quotient(HinduLunarDate.longitude(critical), angle(0, 800, 0)) + 1
def alt_sunrise(cls, date): """Return the astronomical sunrise at Hindu location on date, date, per Lahiri, rounded to nearest minute, as a rational number.""" rise = cls.UJJAIN.dawn(date, angle(0, 47, 0)) return 1/24 * 1/60 * iround(rise * 24 * 60)
def sine(cls, theta): """Return the linear interpolation for angle, theta, in Hindu table.""" entry = theta / angle(0, 225, 0) fraction = mod(entry, 1) return ((fraction * cls.sine_table(iceiling(entry))) + ((1 - fraction) * cls.sine_table(ifloor(entry))))
def sine_table(cls, entry): """Return the value for entry in the Hindu sine table. Entry, entry, is an angle given as a multiplier of 225'.""" exact = 3438 * sin_degrees(entry * angle(0, 225, 0)) error = 0.215 * signum(exact) * signum(abs(exact) - 1716) return iround(exact + error) / 3438
def equation_of_time(cls, date): """Return the time from true to mean midnight of date, date.""" offset = cls.sine(cls.mean_position(date, cls.ANOMALISTIC_YEAR)) equation_sun = (offset * angle(57, 18, 0) * (14/360 - (abs(offset) / 1080))) return ((cls.daily_motion(date) / 360) * (equation_sun / 360) * cls.SIDEREAL_YEAR)
def precise_obliquity(cls, tee): """Return precise (mean) obliquity of ecliptic at moment tee.""" u = cls.julian_centuries(tee) / 100 #assert(abs(u) < 1, # 'Error! This formula is valid for +/-10000 years around J2000.0') return (poly(u, [angle(23, 26, mpf(21.448)), angle(0, 0, mpf(-4680.93)), angle(0, 0, mpf(- 1.55)), angle(0, 0, mpf(+1999.25)), angle(0, 0, mpf(- 51.38)), angle(0, 0, mpf(- 249.67)), angle(0, 0, mpf(- 39.05)), angle(0, 0, mpf(+ 7.12)), angle(0, 0, mpf(+ 27.87)), angle(0, 0, mpf(+ 5.79)), angle(0, 0, mpf(+ 2.45))]))
elif month == HebrewMonth.KISLEV and day < 30: extra = [DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday] elif month == HebrewMonth.KISLEV and day == 30: extra = [DayOfWeek.Monday] elif month in [HebrewMonth.TEVET, HebrewMonth.SHEVAT]: extra = [DayOfWeek.Sunday, DayOfWeek.Monday] elif month == HebrewMonth.ADAR and day < 30: extra = [DayOfWeek.Sunday, DayOfWeek.Monday] else: extra = [DayOfWeek.Sunday] basic.extend(extra) return map(lambda x: DayOfWeek.from_fixed(x + n), basic) JAFFA = Location(angle(32, 1, 60), angle(34, 45, 0), 0, Clock.days_from_hours(2)) class HebrewObservationalDate(YearMonthDay): def __init__(self, year, month, day): YearMonthDay.__init__(self, year, month, day) def to_fixed(self): """Return fixed date equivalent to Observational Hebrew date.""" year1 = self.year - 1 if self.month >= HebrewMonth.TISHRI else self.year start = HebrewDate(year1, HebrewMonth.NISAN, 1).to_fixed() g_year = GregorianDate.to_year(start + 60) new_year = self.new_year(g_year) midmonth = new_year + iround(29.5 * (self.month - 1)) + 15 return JAFFA.phasis_on_or_before(midmonth) + self.day - 1