def new_year(cls, gregorian_year): """Return fixed date of Observational (classical) Nisan 1 occurring in Gregorian year, 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) equinox = Solar.solar_longitude_after(Astro.SPRING, jan1) sset = JAFFA.universal_from_standard(JAFFA.sunset(ifloor(equinox))) return cls.phasis_on_or_after(ifloor(equinox) - (14 if (equinox < sset) else 13), JAFFA)
def to_fixed(self): """Return fixed date of Bahai date, b_date.""" years = (361 * (self.major - 1)) + (19 * (self.cycle - 1)) + self.year if self.month == 19: return self.new_year_on_or_before(self.EPOCH + ifloor(Solar.MEAN_TROPICAL_YEAR * (years + 1/2))) - 20 + self.day elif self.month == self.AYYAM_I_HA: return self.new_year_on_or_before(self.EPOCH + ifloor(Solar.MEAN_TROPICAL_YEAR * (years - 1/2))) + 341 + self.day else: return self.new_year_on_or_before(self.EPOCH + ifloor(Solar.MEAN_TROPICAL_YEAR * (years - 1/2))) + (19 * (self.month - 1)) + self.day - 1
def tropical_longitude(cls, fixed_date): """Return the Hindu tropical longitude on fixed date, 'fixed_date'. Assumes precession with maximum of 27 degrees and period of 7200 sidereal years (= 1577917828/600 days).""" days = ifloor(fixed_date - OldHindu.EPOCH) precession = 27 - abs(54 - mod(27 + (108 * 600/1577917828 * days), 108)) return mod(cls.solar_longitude(fixed_date) - precession, 360)
def from_fixed(cls, date): """Return Old Hindu solar date equivalent to fixed date date.""" sun = cls.hindu_day_count(date) + Clock.days_from_hours(6) year = quotient(sun, cls.ARYA_SOLAR_YEAR) month = mod(quotient(sun, cls.ARYA_SOLAR_MONTH), 12) + 1 day = ifloor(mod(sun, cls.ARYA_SOLAR_MONTH)) + 1 return OldHinduSolarDate(year, month, day)
def to_fixed(self): """Return fixed date of Astronomical Persian date, p_date.""" temp = (self.year - 1) if (0 < self.year) else self.year new_year = self.new_year_on_or_before(self.EPOCH + 180 + ifloor(Solar.MEAN_TROPICAL_YEAR * temp)) return ((new_year - 1) + ((31 * (self.month - 1)) if (self.month <= 7) else (30 * (self.month - 1) + 6)) + self.day)
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 to_fixed(self): """Return fixed date of Chinese date, c_date.""" mid_year = ifloor(self.EPOCH + ((((self.cycle - 1) * 60) + (self.year - 1) + 1/2) * Solar.MEAN_TROPICAL_YEAR)) new_year = self.new_year_on_or_before(mid_year) p = self.new_moon_on_or_after(new_year + ((self.month - 1) * 29)) d = self.from_fixed(p) prior_new_moon = (p if ((self.month == d.month) and (self.leap == d.leap)) else self.new_moon_on_or_after(1 + p)) return prior_new_moon + self.day - 1
def phasis_on_or_before(self, date): """Return the closest fixed date on or before date 'date', when crescent moon first became visible at location 'location'.""" mean = date - ifloor(Lunar.lunar_phase(date + 1) / 360.0 * Lunar.MEAN_SYNODIC_MONTH) tau = ((mean - 30) if (((date - mean) <= 3) and (not self.visible_crescent(date))) else (mean - 2)) return next_int(tau, lambda d: self.visible_crescent(d))
def from_fixed(cls, fixed_date): """Return the Hindu (Orissa) solar date equivalent to fixed date, 'fixed_date'.""" critical = cls.sunrise(fixed_date + 1) month = cls.zodiac(critical) year = cls.calendar_year(critical) - cls.SOLAR_ERA approx = fixed_date - 3 - mod(ifloor(cls.solar_longitude(critical)), 30) begin = next_int(approx, lambda i: (cls.zodiac(cls.sunrise(i + 1)) == month)) day = fixed_date - begin + 1 return HinduSolarDate(year, month, day)
def from_fixed(cls, fixed_date): """Return the Astronomical Hindu (Tamil) solar date equivalent to fixed date, 'fixed_date'.""" critical = cls.sunset(fixed_date) month = sidereal_zodiac(critical) year = cls.calendar_year(critical) - HinduSolarDate.SOLAR_ERA approx = fixed_date - 3 - mod(ifloor(sidereal_solar_longitude( critical)), 30) begin = next_int(approx, lambda i: (sidereal_zodiac(cls.sunset(i)) == month)) day = fixed_date - begin + 1 return HinduAstroSolar(year, month, day)
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 hindu_lunar_new_year(g_year): """Return the fixed date of Hindu lunisolar new year in Gregorian year, g_year.""" jan1 = GregorianDate.new_year(g_year) mina = hindu_solar_longitude_at_or_after(330, jan1) new_moon = HinduLunarDate.day_at_or_after(1, mina) h_day = ifloor(new_moon) critical = HinduDate.sunrise(h_day) return (h_day + (0 if ((new_moon < critical) or (HinduLunarDate.day_from_moment(HinduDate.sunrise(h_day + 1)) == 2)) else 1))
def hindu_tithi_occur(l_month, tithi, tee, l_year): """Return the fixed date of occurrence of Hindu lunar tithi prior to sundial time, tee, in Hindu lunar month, l_month, and year, l_year.""" approx = hindu_date_occur(l_month, ifloor(tithi), l_year) lunar = HinduLunarDate.day_at_or_after(tithi, approx - 2) ttry = Clock.fixed_from_moment(lunar) tee_h = HinduLunarDate.UJJAIN.standard_from_sundial(ttry + tee) if lunar <= tee_h or HinduLunarDate.lunar_phase(HinduLunarDate.UJJAIN.standard_from_sundial(ttry + 1 + tee)) > 12 * tithi: return ttry else: return ttry + 1
def from_fixed(cls, date): """Return the Hindu lunar date, new_moon scheme, equivalent to fixed date, date.""" critical = cls.sunrise(date) day = cls.lunar_day_from_moment(critical) leap_day = (day == cls.lunar_day_from_moment(cls.sunrise(date - 1))) last_new_moon = cls.new_moon_before(critical) next_new_moon = cls.new_moon_before(ifloor(last_new_moon) + 35) solar_month = cls.zodiac(last_new_moon) leap_month = (solar_month == cls.zodiac(next_new_moon)) month = amod(solar_month + 1, 12) year = cls.calendar_year((date + 180) if (month <= 2) else date) - cls.LUNAR_ERA return HinduLunarDate(year, month, leap_month, day, leap_day)
def from_fixed(cls, fixed_date): """Return Chinese date (cycle year month leap day) of fixed date, 'fixed_date'.""" s1 = cls.winter_solstice_on_or_before(fixed_date) s2 = cls.winter_solstice_on_or_before(s1 + 370) next_m11 = cls.new_moon_before(1 + s2) m12 = cls.new_moon_on_or_after(1 + s1) leap_year = iround((next_m11 - m12) / Lunar.MEAN_SYNODIC_MONTH) == 12 m = cls.new_moon_before(1 + fixed_date) month = amod(iround((m - m12) / Lunar.MEAN_SYNODIC_MONTH) - (1 if (leap_year and cls.is_prior_leap_month(m12, m)) else 0), 12) leap_month = (leap_year and cls.is_no_major_solar_term(m) and (not cls.is_prior_leap_month(m12, cls.new_moon_before(m)))) elapsed_years = (ifloor(mpf(1.5) - (month / 12) + ((fixed_date - cls.EPOCH) / Solar.MEAN_TROPICAL_YEAR))) cycle = 1 + quotient(elapsed_years - 1, 60) year = amod(elapsed_years, 60) day = 1 + (fixed_date - m) return ChineseDate(cycle, year, month, leap_month, day)
def to_fixed(self): """Return the fixed date of this Hindu lunar date.""" approx = OldHindu.EPOCH + (self.SIDEREAL_YEAR * (self.year + self.LUNAR_ERA + ((self.month - 1) / 12))) s = ifloor(approx - ((1/360) * self.SIDEREAL_YEAR * mod(self.hindu_solar_longitude(approx) - ((self.month - 1) * 30) + 180, 360) - 180)) k = self.lunar_day_from_moment(s + Clock.days_from_hours(6)) if (3 < k < 27): temp = k else: mid = self.lunar_from_fixed(s - 15) if ((mid.month != self.month) or (mid.leap_month and not self.leap_month)): temp = mod(k + 15, 30) - 15 else: temp = mod(k - 15, 30) + 15 est = s + self.day - temp tau = est - mod(self.lunar_day_from_moment(est + Clock.days_from_hours(6)) - self.day + 15, 30) + 15 date = next_int(tau - 1, lambda d: self.lunar_day_from_moment(self.sunrise(d)) in [self.day, amod(self.day + 1, 30)]) return date + 1 if self.leap_day else date
def sundial_time(cls, tee): """Return Hindu local time of temporal moment, tee.""" date = Clock.fixed_from_moment(tee) time = mod(tee, 1) q = ifloor(4 * time) if q == 0: a = cls.sunset(date - 1) b = cls.sunrise(date) t = Clock.days_from_hours(-6) elif q == 3: a = cls.sunset(date) b = cls.sunrise(date + 1) t = Clock.days_from_hours(18) else: a = cls.sunrise(date) b = cls.sunset(date) t = Clock.days_from_hours(6) return a + (2 * (b - a) * (time - t))
def ephemeris_correction(cls, tee): """Return Dynamical Time minus Universal Time (in days) for moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1991.""" year = GregorianDate.to_year(ifloor(tee)) c = GregorianDate.date_difference(GregorianDate(1900, JulianMonth.January, 1), GregorianDate(year, JulianMonth.July, 1)) / mpf(36525) if 1988 <= year <= 2019: return 1/86400 * (year - 1933) elif 1900 <= year <= 1987: return poly(c, [mpf(-0.00002), mpf(0.000297), mpf(0.025184), mpf(-0.181133), mpf(0.553040), mpf(-0.861938), mpf(0.677066), mpf(-0.212591)]) elif 1800 <= year <= 1899: return poly(c, [mpf(-0.000009), mpf(0.003844), mpf(0.083563), mpf(0.865736), mpf(4.867575), mpf(15.845535), mpf(31.332267), mpf(38.291999), mpf(28.316289), mpf(11.636204), mpf(2.043794)]) elif 1700 <= year <= 1799: return 1/86400 * poly(year - 1700, [8.118780842, -0.005092142, 0.003336121, -0.0000266484]) elif 1620 <= year <= 1699: return 1/86400 * poly(year - 1600, [mpf(196.58333), mpf(-4.0675), mpf(0.0219167)]) else: x = Clock.days_from_hours(mpf(12)) + GregorianDate.date_difference(GregorianDate(1810, JulianMonth.January, 1), GregorianDate(year, JulianMonth.January, 1)) return 1/86400 * (((x * x) / mpf(41048480)) - 15)
def to_fixed(self): """Return the fixed date corresponding to Hindu lunar date, l_date.""" approx = (OldHindu.EPOCH + self.MEAN_SIDEREAL_YEAR * (self.year + self.LUNAR_ERA + ((self.month - 1) / 12))) s = ifloor(approx - 1/360 * self.MEAN_SIDEREAL_YEAR * (mod(sidereal_solar_longitude(approx) - (self.month - 1) * 30 + 180, 360) - 180)) k = self.day_from_moment(s + Clock.days_from_hours(6)) if (3 < k < 27): temp = k else: mid = self.from_fixed(s - 15) if ((mid.month != self.month) or (mid.leap_month and not self.leap_month)): temp = mod(k + 15, 30) - 15 else: temp = mod(k - 15, 30) + 15 est = s + self.day - temp tau = est - mod(self.day_from_moment(est + Clock.days_from_hours(6)) - self.day + 15, 30) + 15 date = next_int(tau - 1, lambda d: (self.day_from_moment(self.alt_sunrise(d)) in [self.day, amod(self.day + 1, 30)])) return (date + 1) if self.leap_day else date
def winter_solstice_on_or_before(cls, fixed_date): """Return fixed date, in the Chinese zone, of winter solstice on or before fixed date, 'fixed_date'.""" approx = Solar.estimate_prior_solar_longitude(Astro.WINTER, cls.midnight(fixed_date + 1)) return next_int(ifloor(approx) - 1, lambda day: Astro.WINTER < Solar.solar_longitude(cls.midnight(1 + day)))
def new_year_on_or_before(cls, fixed_date): """Return fixed date of Future Bahai New Year on or before fixed date, 'fixed_date'.""" approx = Solar.estimate_prior_solar_longitude(Astro.SPRING, cls.sunset_in_haifa(fixed_date)) return next_int(ifloor(approx) - 1, lambda day: Solar.solar_longitude(cls.sunset_in_haifa(day)) <= Astro.SPRING + 2)
def qing_ming(cls, gregorian_year): """Return fixed date of Qingming occurring in Gregorian year, 'gregorian_year'.""" return ifloor(cls.minor_solar_term_on_or_after( GregorianDate(gregorian_year, MonthOfYear.March, 30).to_fixed()))
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 new_year_on_or_before(cls, date): """Return the fixed date of Astronomical Persian New Year on or before fixed date, date.""" approx = Solar.estimate_prior_solar_longitude(Astro.SPRING, cls.midday_in_tehran(date)) return next_int(ifloor(approx) - 1, lambda day: (Solar.solar_longitude(cls.midday_in_tehran(day)) <= (Astro.SPRING + 2)))
def to_fixed(self): """Return fixed date equivalent to Observational Islamic date, i_date.""" midmonth = self.EPOCH + ifloor((((self.year - 1) * 12) + self.month - 0.5) * Lunar.MEAN_SYNODIC_MONTH) return (self.LOCATION.phasis_on_or_before(midmonth) + self.day - 1)
def to_fixed(self): return ifloor(self.to_moment())
def to_fixed(self): """Return the fixed date corresponding to Astronomical Hindu solar date (Tamil rule; Saka era).""" approx = OldHindu.EPOCH - 3 + ifloor(((self.year + HinduSolarDate.SOLAR_ERA) + ((self.month - 1) / 12)) * self.MEAN_SIDEREAL_YEAR) begin = next_int(approx, lambda i: sidereal_zodiac(self.sunset(i)) == self.month) return begin + self.day - 1
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 to_fixed(self): """Return the fixed date corresponding to Hindu solar date, s_date, (Saka era; Orissa rule.)""" begin = ifloor((self.year + self.SOLAR_ERA + ((self.month - 1)/12)) * self.SIDEREAL_YEAR + OldHindu.EPOCH) return self.day - 1 + next_int(begin - 3, lambda d: self.zodiac(self.sunrise(d + 1)) == self.month)
def new_moon_on_or_after(cls, fixed_date): """Return fixed date (Beijing) of first new moon on or after fixed date, 'fixed_date'.""" tee = Lunar.new_moon_at_or_after(cls.midnight(fixed_date)) return ifloor(cls.chinese_location(tee).standard_from_universal(tee))