def toordinal(self): """Return the ordinal 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 = int( math.floor(approx - 1 / 360 * self.MEAN_SIDEREAL_YEAR * (((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.fromordinal(s - 15) if ((mid.month != self.month) or (mid.leap_month and not self.leap_month)): temp = ((k + 15) % 30) - 15 else: temp = ((k - 15) % 30) + 15 est = s + self.day - temp tau = est - ((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 approx_moment_of_depression(self, tee, alpha, early): """Return the moment in local time near tee when depression angle of sun is alpha (negative if above horizon) at location; early is true when MORNING event is sought and false for EVENING. Raise VlueError if depression angle is not reached.""" ttry = self.sine_offset(tee, alpha) date = Clock.ordinal_from_moment(tee) if alpha >= 0: if early: alt = date else: alt = date + 1 else: alt = date + Clock.days_from_hours(12) if abs(ttry) > 1: value = self.sine_offset(alt, alpha) else: value = ttry if abs(value) <= 1: temp = -1 if early else 1 temp *= mod(Clock.days_from_hours(12) + arcsin_degrees(value) / 360, 1) - Clock.days_from_hours(6) temp += date + Clock.days_from_hours(12) return self.local_from_apparent(temp) else: raise ValueError("Depression angle not reached")
def toordinal(self): """Return the ordinal date of this Hindu lunar date.""" approx = OldHindu.EPOCH + (self.SIDEREAL_YEAR * (self.year + self.LUNAR_ERA + ((self.month - 1) / 12))) s = int( math.floor(approx - ((1 / 360) * self.SIDEREAL_YEAR * ((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_fromordinal(s - 15) if ((mid.month != self.month) or (mid.leap_month and not self.leap_month)): temp = ((k + 15) % 30) - 15 else: temp = ((k - 15) % 30) + 15 est = s + self.day - temp tau = est - ( (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 location(cls, tee): """Return location of Beijing; time zone varies with time, tee.""" year = GregorianDate.to_year(int(math.floor(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 japanese_location(tee): """Return the location for Japanese calendar; varies with moment, tee.""" year = GregorianDate.to_year(int(math.floor(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 fromordinal(cls, ordinal): """Return Old Hindu solar date equivalent to ordinal date ordinal.""" sun = cls.hindu_day_count(ordinal) + Clock.days_from_hours(6) year = int(math.floor(sun / cls.ARYA_SOLAR_YEAR)) month = (int(math.floor(sun / cls.ARYA_SOLAR_MONTH)) % 12) + 1 day = int(math.floor(sun % cls.ARYA_SOLAR_MONTH)) + 1 return OldHinduSolarDate(year, month, day)
def equation_of_time(tee): """Return the equation of time (as fraction of day) for moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1991.""" c = julian_centuries(tee) lamb = poly(c, [mpf(280.46645), mpf(36000.76983), mpf(0.0003032)]) anomaly = poly( c, [mpf(357.52910), mpf(35999.05030), mpf(-0.0001559), mpf(-0.00000048)]) eccentricity = poly( c, [mpf(0.016708617), mpf(-0.000042037), mpf(-0.0000001236)]) varepsilon = obliquity(tee) y = pow(tan_degrees(varepsilon / 2), 2) equation = ( (1 / 2 / pi) * (y * sin_degrees(2 * lamb) + -2 * eccentricity * sin_degrees(anomaly) + (4 * eccentricity * y * sin_degrees(anomaly) * cos_degrees(2 * lamb)) + -0.5 * y * y * sin_degrees(4 * lamb) + -1.25 * eccentricity * eccentricity * sin_degrees(2 * anomaly))) return signum(equation) * min(abs(equation), Clock.days_from_hours( mpf(12)))
class BahaiDate(object): EPOCH = GregorianDate(1844, MonthOfYear.MARCH, 21).toordinal() HAIFA = Location(mpf(32.82), 35, 0, Clock.days_from_hours(2)) AYYAM_I_HA = 0 def __init__(self, major, cycle, year, month, day): self.major = major self.cycle = cycle self.year = year self.month = month self.day = day def to_tuple(self): return (self.major, self.cycle, self.year, self.month, self.day) def toordinal(self): raise NotImplementedError() @classmethod def fromordinal(cls, ordinal): raise NotImplementedError() @classmethod def new_year(cls, gregorian_year): """Return ordinal date of Bahai New Year in Gregorian year, 'gregorian_year'.""" return GregorianDate(gregorian_year, MonthOfYear.MARCH, 21).toordinal() @classmethod def sunset_in_haifa(cls, ordinal): """Return universal time of sunset of evening before ordinal date in Haifa.""" return cls.HAIFA.universal_from_standard(cls.HAIFA.sunset(ordinal)) def __eq__(self, other): return isinstance(other, BahaiDate) and all( map(lambda (x, y): x == y, zip(self.to_tuple(), other.to_tuple()))) def __ne__(self, other): return not self.__eq__(other) def __lt__(self, other): return isinstance(other, BahaiDate) and reduce_cond( lambda _, (x, y): x < y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __le__(self, other): return isinstance(other, BahaiDate) and reduce_cond( lambda _, (x, y): x <= y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __gt__(self, other): return isinstance(other, BahaiDate) and reduce_cond( lambda _, (x, y): x > y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __ge__(self, other): return isinstance(other, BahaiDate) and reduce_cond( lambda _, (x, y): x >= y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False)
class ObservationalIslamicDate(IslamicDate): # (Cairo, Egypt). LOCATION = Location(mpf(30.1), mpf(31.3), 200, Clock.days_from_hours(2)) def __init__(self, year, month, day): IslamicDate.__init__(self, year, month, day) def toordinal(self): """Return ordinal date equivalent to Observational Islamic date, i_date.""" midmonth = self.EPOCH + int( math.floor((((self.year - 1) * 12) + self.month - 0.5) * MEAN_SYNODIC_MONTH)) return (self.LOCATION.phasis_on_or_before(midmonth) + self.day - 1) @classmethod def fromordinal(cls, ordinal): """Return Observational Islamic date (year month day) corresponding to ordinal date, 'ordinal'.""" crescent = cls.LOCATION.phasis_on_or_before(ordinal) elapsed_months = int(round( (crescent - cls.EPOCH) / MEAN_SYNODIC_MONTH)) year = int(math.floor(elapsed_months / 12)) + 1 month = (elapsed_months % 12) + 1 day = (ordinal - crescent) + 1 return ObservationalIslamicDate(year, month, day)
def molad(cls, month, year): """Return moment of mean conjunction of month in Hebrew year.""" y = year + 1 if month < HebrewMonth.TISHRI else year months_elapsed = month - HebrewMonth.TISHRI + int( math.floor((235 * y - 234) / 19)) return cls.EPOCH - Fraction(876, 25920) + months_elapsed * ( 29 + Clock.days_from_hours(12) + Fraction(793, 25920))
def sunrise(cls, date): """Return the sunrise at hindu_location on date, date.""" return (date + Clock.days_from_hours(6) + ((cls.UJJAIN.longitude - cls.LOCATION.longitude) / 360) - cls.equation_of_time(date) + ((1577917828 / 1582237828 / 360) * (cls.ascensional_difference(date, cls.LOCATION) + (1 / 4 * cls.solar_sidereal_difference(date)))))
def sunset(cls, date): """Return sunset at HINDU_LOCATION on date, date.""" return (date + Clock.days_from_hours(18) + ((cls.UJJAIN.longitude - cls.LOCATION.longitude) / 360) - cls.equation_of_time(date) + (((1577917828 / 1582237828) / 360) * (-cls.ascensional_difference(date, cls.LOCATION) + (3 / 4 * cls.solar_sidereal_difference(date)))))
def sundial_time(cls, tee): """Return Hindu local time of temporal moment, tee.""" date = Clock.ordinal_from_moment(tee) time = tee % 1 q = int(math.floor(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 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 fromordinal(cls, ordinal): """Return Old Hindu lunar date equivalent to ordinal date 'ordinal'.""" sun = cls.hindu_day_count(ordinal) + Clock.days_from_hours(6) new_moon = sun - (sun % cls.ARYA_LUNAR_MONTH) leap = cls.ARYA_SOLAR_MONTH - cls.ARYA_LUNAR_MONTH >= new_moon % cls.ARYA_SOLAR_MONTH and new_moon % cls.ARYA_SOLAR_MONTH > 0 month = 1 + int(math.ceil(new_moon / cls.ARYA_SOLAR_MONTH) % 12) day = (int(math.floor(sun / cls.ARYA_LUNAR_DAY)) % 30) + 1 year = int( math.ceil( (new_moon + cls.ARYA_SOLAR_MONTH) / cls.ARYA_SOLAR_YEAR)) - 1 return OldHinduLunarDate(year, month, leap, day)
def moonrise(self, date): """Return the standard time of moonrise on fixed, date, and location, location.""" t = self.universal_from_standard(date) waning = (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()
def ephemeris_correction(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(int(math.floor(tee))) c = GregorianDate.date_difference( GregorianDate(1900, MonthOfYear.JANUARY, 1), GregorianDate(year, MonthOfYear.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, MonthOfYear.JANUARY, 1), GregorianDate(year, MonthOfYear.JANUARY, 1)) return 1 / 86400 * (((x * x) / mpf(41048480)) - 15)
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).toordinal()): #local mean time for longitude 126 deg 58 min z = 3809 / 450 elif (tee < GregorianDate(1912, MonthOfYear.JANUARY, 1).toordinal()): z = 8.5 elif (tee < GregorianDate(1954, MonthOfYear.MARCH, 21).toordinal()): z = 9 elif (tee < GregorianDate(1961, MonthOfYear.AUGUST, 10).toordinal()): z = 8.5 else: z = 9 return Location(angle(37, 34, 0), angle(126, 58, 0), 0, Clock.days_from_hours(z))
def toordinal(self): """Return ordinal date corresponding to Old Hindu lunar date l_date.""" mina = ((12 * self.year) - 1) * self.ARYA_SOLAR_MONTH lunar_new_year = self.ARYA_LUNAR_MONTH * ( int(math.floor(mina / self.ARYA_LUNAR_MONTH)) + 1) if not self.leap and int( math.ceil((lunar_new_year - mina) / (self.ARYA_SOLAR_MONTH - self.ARYA_LUNAR_MONTH))) <= self.month: temp = self.month else: temp = self.month - 1 temp = self.EPOCH + lunar_new_year + (self.ARYA_LUNAR_MONTH * temp) + ( (self.day - 1) * self.ARYA_LUNAR_DAY) + Clock.days_from_hours(-6) return int(math.ceil(temp))
def rama(gregorian_year): """Return the list of ordinal date(s) of Rama's Birthday in Gregorian year, 'gregorian_year'.""" return hindu_lunar_event(1, 9, Clock.days_from_hours(12), gregorian_year)
def shiva(gregorian_year): """Return the list of ordinal date(s) of Night of Shiva in Gregorian year, 'gregorian_year'.""" return hindu_lunar_event(11, 29, Clock.days_from_hours(24), gregorian_year)
from mpmath import mpf, pi import math from jetblack.calendars.datemath import MonthOfYear from jetblack.calendars.timemath import Clock from jetblack.calendars.systems.gregorian import GregorianDate from jetblack.calendars.utils import poly, signum from jetblack.calendars.trigonometry import angle, sin_degrees, cos_degrees, tan_degrees, arcsin_degrees, arctan_degrees, secs J2000 = Clock.days_from_hours(mpf(12)) + GregorianDate.new_year(2000) def zone_from_longitude(phi): """Return the difference between UT and local mean time at longitude 'phi' as a fraction of a day.""" return phi / 360 def ephemeris_correction(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(int(math.floor(tee))) c = GregorianDate.date_difference( GregorianDate(1900, MonthOfYear.JANUARY, 1), GregorianDate(year, MonthOfYear.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),
def asr(date, location): """Return standard time of asr on fixed date, date, at location, location.""" noon = location.universal_from_standard(location.midday(date)) phi = location.latitude delta = declination(noon, 0, solar_longitude(noon)) altitude = delta - phi - 90 h = arctan_degrees(tan_degrees(altitude), 2 * tan_degrees(altitude) + 1) # For Shafii use instead: # tan_degrees(altitude) + 1) return location.dusk(date, -h) JERUSALEM = Location(mpf(31.8), mpf(35.2), 800, Clock.days_from_hours(2)) def astronomical_easter(g_year): """Return date of (proposed) astronomical Easter in Gregorian year, g_year.""" jan1 = GregorianDate.new_year(g_year) equinox = solar_longitude_after(Season.SPRING, jan1) paschal_moon = int( math.floor( JERUSALEM.apparent_from_local( JERUSALEM.local_from_universal( lunar_phase_at_or_after(MoonPhase.FULL, equinox))))) # Return the Sunday following the Paschal moon. return DayOfWeek(DayOfWeek.SUNDAY).after(paschal_moon)
at location, location, as a small positive/negative angle in degrees, ignoring parallax and refraction. Adapted from 'Astronomical Algorithms' by Jean Meeus, Willmann_Bell, Inc., 1998.""" lamb = lunar_longitude(tee) beta = lunar_latitude(tee) alpha =right_ascension(tee, beta, lamb) delta = declination(tee, beta, lamb) theta0 = 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_phase(tee) altitude = self.lunar_altitude(tee) arc_of_light = arccos_degrees(cos_degrees(lunar_latitude(tee)) * cos_degrees(phase)) return ((MoonPhase.NEW < phase < MoonPhase.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 jewish_morning_end(date, location): """Return standard time on fixed date, date, at location, location, of end of morning according to Jewish ritual.""" return location.standard_from_sundial(date + Clock.days_from_hours(10))
class HinduDate(object): SIDEREAL_YEAR = 365 + 279457 / 1080000 ANOMALISTIC_YEAR = 1577917828000 / (4320000000 - 387) CREATION = OldHindu.EPOCH - 1955880000 * SIDEREAL_YEAR UJJAIN = Location(angle(23, 9, 0), angle(75, 46, 6), 0, Clock.days_from_hours(5 + 461 / 9000)) LOCATION = UJJAIN def __init__(self, year, month, leap_month, day, leap_day): self.year = year self.month = month self.leap_month = leap_month self.day = day self.leap_day = leap_day def to_tuple(self): return (self.year, self.month, self.leap_month, self.day, self.leap_day) def __eq__(self, other): return isinstance(other, HinduDate) and all( map(lambda (x, y): x == y, zip(self.to_tuple(), other.to_tuple()))) def __ne__(self, other): return not self.__eq__(other) def __lt__(self, other): return isinstance(other, HinduDate) and reduce_cond( lambda _, (x, y): x < y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __le__(self, other): return isinstance(other, HinduDate) and reduce_cond( lambda _, (x, y): x <= y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __gt__(self, other): return isinstance(other, HinduDate) and reduce_cond( lambda _, (x, y): x > y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) def __ge__(self, other): return isinstance(other, HinduDate) and reduce_cond( lambda _, (x, y): x >= y, lambda r, (x, y): not r and x == y, zip(self.to_tuple(), other.to_tuple()), False) @classmethod 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 int(round(exact + error)) / 3438 @classmethod def sine(cls, theta): """Return the linear interpolation for angle, theta, in Hindu table.""" entry = theta / angle(0, 225, 0) fraction = entry % 1 return ((fraction * cls.sine_table(int(math.ceil(entry)))) + ((1 - fraction) * cls.sine_table(int(math.floor(entry))))) @classmethod 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)))) @classmethod def mean_position(cls, tee, period): """Return the position in degrees at moment, tee, in uniform circular orbit of period days.""" return 360 * (((tee - cls.CREATION) / period) % 1) @classmethod def true_position(cls, tee, period, size, anomalistic, change): """Return the longitudinal position at moment, tee. period is the period of mean motion in days. size is ratio of radii of epicycle and deferent. anomalistic is the period of retrograde revolution about epicycle. change is maximum decrease in epicycle size.""" lam = cls.mean_position(tee, period) offset = cls.sine(cls.mean_position(tee, anomalistic)) contraction = abs(offset) * change * size equation = cls.arcsin(offset * (size - contraction)) return (lam - equation) % 360 @classmethod def solar_longitude(cls, tee): """Return the solar longitude at moment, tee.""" return cls.true_position(tee, cls.SIDEREAL_YEAR, 14 / 360, cls.ANOMALISTIC_YEAR, 1 / 42) @classmethod def zodiac(cls, tee): """Return the zodiacal sign of the sun, as integer in range 1..12, at moment tee.""" return int(math.floor(float(cls.solar_longitude(tee)), 30)) + 1 @classmethod 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) @classmethod def ascensional_difference(cls, date, location): """Return the difference between right and oblique ascension of sun on date, date, at loacel, location.""" sin_delta = (1397 / 3438) * cls.sine(cls.tropical_longitude(date)) phi = location.latitude diurnal_radius = cls.sine(90 + cls.arcsin(sin_delta)) tan_phi = cls.sine(phi) / cls.sine(90 + phi) earth_sine = sin_delta * tan_phi return cls.arcsin(-earth_sine / diurnal_radius) @classmethod 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 = int(math.floor(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) @classmethod def solar_sidereal_difference(cls, date): """Return the difference between solar and sidereal day on date, date.""" return cls.daily_motion(date) * cls.rising_sign(date) @classmethod def sunrise(cls, date): """Return the sunrise at hindu_location on date, date.""" return (date + Clock.days_from_hours(6) + ((cls.UJJAIN.longitude - cls.LOCATION.longitude) / 360) - cls.equation_of_time(date) + ((1577917828 / 1582237828 / 360) * (cls.ascensional_difference(date, cls.LOCATION) + (1 / 4 * cls.solar_sidereal_difference(date))))) @classmethod def sunset(cls, date): """Return sunset at HINDU_LOCATION on date, date.""" return (date + Clock.days_from_hours(18) + ((cls.UJJAIN.longitude - cls.LOCATION.longitude) / 360) - cls.equation_of_time(date) + (((1577917828 / 1582237828) / 360) * (-cls.ascensional_difference(date, cls.LOCATION) + (3 / 4 * cls.solar_sidereal_difference(date))))) @classmethod 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 * int(round(rise * 24 * 60))
def toordinal(self): """Return ordinal date corresponding to Old Hindu solar date s_date.""" return int( math.ceil(self.EPOCH + self.year * self.ARYA_SOLAR_YEAR + (self.month - 1) * self.ARYA_SOLAR_MONTH + self.day + Clock.days_from_hours(-30)))
def dawn(self, date, alpha): """Return standard time in morning on fixed date date at location location when depression angle of sun is alpha.""" result = self.moment_of_depression(date + Clock.days_from_hours(6), alpha, self.MORNING) return self.standard_from_local(result)
def dusk(self, date, alpha): """Return standard time in evening on fixed date 'date' at location 'location' when depression angle of sun is alpha.""" result = self.moment_of_depression(date + Clock.days_from_hours(18), alpha, self.EVENING) return self.standard_from_local(result)
def midday(self, date): """Return standard time on fixed date, date, of midday at location, location.""" return self.standard_from_local(self.local_from_apparent(date + Clock.days_from_hours(mpf(12))))