def fromordinal(cls, ordinal): """Return Bahai date [major, cycle, year, month, day] corresponding to ordinal date.""" g_year = GregorianDate.to_year(ordinal) start = GregorianDate.to_year(cls.EPOCH) years = (g_year - start - (1 if (ordinal <= GregorianDate( g_year, MonthOfYear.MARCH, 20).toordinal()) else 0)) major = 1 + int(math.floor(years / 361)) cycle = 1 + int(math.floor((years % 361) / 19)) year = 1 + years % 19 days = ordinal - WesternBahaiDate(major, cycle, year, 1, 1).toordinal() # month if ordinal >= WesternBahaiDate(major, cycle, year, 19, 1).toordinal(): month = 19 elif ordinal >= WesternBahaiDate(major, cycle, year, cls.AYYAM_I_HA, 1).toordinal(): month = cls.AYYAM_I_HA else: month = 1 + int(math.floor(days / 19)) day = ordinal + 1 - WesternBahaiDate(major, cycle, year, month, 1).toordinal() return WesternBahaiDate(major, cycle, year, month, day)
def hindu_lunar_holiday(l_month, l_day, gregorian_year): """Return the list of ordinal dates of occurrences of Hindu lunar month, month, day, day, in Gregorian year, 'gregorian_year'.""" l_year = HinduLunarDate.fromordinal( GregorianDate.new_year(gregorian_year)).year date1 = hindu_date_occur(l_month, l_day, l_year) date2 = hindu_date_occur(l_month, l_day, l_year + 1) return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def new_year(cls, gregorian_year): """Return the list of ordinal dates of Tibetan New Year in Gregorian year, 'gregorian_year'.""" dec31 = GregorianDate.year_end(gregorian_year) t_year = cls.fromordinal(dec31).year return list_range( [cls.losar(t_year - 1), cls.losar(t_year)], GregorianDate.year_range(gregorian_year))
def testUniversalFromDynamical(self): date = GregorianDate(1977, MonthOfYear.FEBRUARY, 18) time = Clock(3, 37, 40).to_time() td = date.toordinal() + time utc = universal_from_dynamical(td) clk = Clock.from_moment(utc) self.assertEqual(clk.hour, 3) self.assertEqual(clk.minute, 36) self.assertEqual(int(round(clk.second)), 52)
def julian_in_gregorian(julian_month, julian_day, gregorian_year): """Return the list of the ordinal dates of Julian month 'julian_month', day 'julian_day' that occur in Gregorian year 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = JulianDate.fromordinal(jan1).year y_prime = 1 if (y == -1) else (y + 1) date1 = JulianDate(y, julian_month, julian_day).toordinal() date2 = JulianDate(y_prime, julian_month, julian_day).toordinal() return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def in_gregorian(cls, coptic_month, coptic_day, gregorian_year): """Return the list of the ordinal dates of Coptic month 'coptic_month', day 'coptic_day' that occur in Gregorian year 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = cls.fromordinal(jan1).year date1 = CopticDate(y, coptic_month, coptic_day).toordinal() date2 = CopticDate(y + 1, coptic_month, coptic_day).toordinal() return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def yahrzeit_in_gregorian(self, gregorian_year): """Return the list of the ordinal dates of death date death_date (yahrzeit) that occur in Gregorian year 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = HebrewDate.fromordinal(jan1).year date1 = self.yahrzeit(y) date2 = self.yahrzeit(y + 1) return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def birthday_in_gregorian(self, gregorian_year): """Return the list of the ordinal dates of Hebrew birthday birthday that occur in Gregorian 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = HebrewDate.fromordinal(jan1).year date1 = self.birthday(y) date2 = self.birthday(y + 1) return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def hindu_lunar_event(l_month, tithi, tee, gregorian_year): """Return the list of ordinal dates of occurrences of Hindu lunar tithi prior to sundial time, tee, in Hindu lunar month, l_month, in Gregorian year, 'gregorian_year'.""" l_year = HinduLunarDate.fromordinal( GregorianDate.new_year(gregorian_year)).year date1 = hindu_tithi_occur(l_month, tithi, tee, l_year) date2 = hindu_tithi_occur(l_month, tithi, tee, l_year + 1) return list_range([date1, date2], GregorianDate.year_range(gregorian_year))
def in_gregorian(cls, month, day, gregorian_year): """Return list of the ordinal dates of Islamic month 'month', day 'day' that occur in Gregorian year 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = cls.fromordinal(jan1).year date1 = IslamicDate(y, month, day).toordinal() date2 = IslamicDate(y + 1, month, day).toordinal() date3 = IslamicDate(y + 2, month, day).toordinal() return list_range([date1, date2, date3], GregorianDate.year_range(gregorian_year))
def tzom_tevet(cls, gregorian_year): """Return the list of ordinal dates for Tzom Tevet (Tevet 10) that occur in Gregorian year 'gregorian_year'. It can occur 0, 1 or 2 times per Gregorian year.""" jan1 = GregorianDate.new_year(gregorian_year) y = HebrewDate.fromordinal(jan1).year d1 = HebrewDate(y, HebrewMonth.TEVET, 10).toordinal() d1 = d1 + (1 if weekday_fromordinal(d1) == DayOfWeek.SATURDAY else 0) d2 = HebrewDate(y + 1, HebrewMonth.TEVET, 10).toordinal() d2 = d2 + (1 if weekday_fromordinal(d2) == DayOfWeek.SATURDAY else 0) dates = [d1, d2] return list_range(dates, GregorianDate.year_range(gregorian_year))
def in_gregorian(cls, month, day, gregorian_year): """Return list of the ordinal dates of Hebrew month, 'month', day, 'day', that occur in Gregorian year 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) y = HebrewDate.fromordinal(jan1).year date1 = HebrewDate(y, month, day).toordinal() date2 = HebrewDate(y + 1, month, day).toordinal() # Hebrew and Gregorian calendar are aligned but certain # holidays, i.e. Tzom Tevet, can fall on either side of Jan 1. # So we can have 0, 1 or 2 occurences of that holiday. dates = [date1, date2] return list_range(dates, GregorianDate.year_range(gregorian_year))
def testNewYear(self): self.assertEqual(ChineseDate.new_year(2015), GregorianDate(2015, 2, 19).toordinal(), "Thursday, 19 February 2015") self.assertEqual(ChineseDate.new_year(2016), GregorianDate(2016, 2, 8).toordinal(), "Monday, 8 February 2016") self.assertEqual(ChineseDate.new_year(2017), GregorianDate(2017, 1, 28).toordinal(), "Saturday, 28 January 2017") self.assertEqual(ChineseDate.new_year(2018), GregorianDate(2018, 2, 16).toordinal(), "Friday, 16 February 2018")
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 dragon_festival(cls, gregorian_year): """Return ordinal date of the Dragon Festival occurring in Gregorian year 'gregorian_year'.""" elapsed_years = 1 + gregorian_year - GregorianDate.to_year(cls.EPOCH) cycle = 1 + int(math.floor((elapsed_years - 1) / 60)) year = amod(elapsed_years, 60) return ChineseDate(cycle, year, 5, False, 5).toordinal()
def toordinal(self): """Return ordinal date equivalent to the Bahai date, b_date.""" g_year = (361 * (self.major - 1) + 19 * (self.cycle - 1) + self.year - 1 + GregorianDate.to_year(self.EPOCH)) if (self.month == self.AYYAM_I_HA): elapsed_months = 342 elif (self.month == 19): if (GregorianDate.is_leap_year(g_year + 1)): elapsed_months = 347 else: elapsed_months = 346 else: elapsed_months = 19 * (self.month - 1) return GregorianDate(g_year, MonthOfYear.MARCH, 20).toordinal() + elapsed_months + self.day
def feast_of_ridvan(cls, gregorian_year): """Return ordinal date of Feast of Ridvan in Gregorian year year, 'gregorian_year'.""" years = gregorian_year - GregorianDate.to_year(cls.EPOCH) major = 1 + int(math.floor(years / 361)) cycle = 1 + int(math.floor((years % 361) / 19)) year = 1 + years % 19 return FutureBahaiDate(major, cycle, year, 2, 13).toordinal()
def qing_ming(cls, gregorian_year): """Return ordinal date of Qingming occurring in Gregorian year, 'gregorian_year'.""" return int( math.floor( cls.minor_solar_term_on_or_after( GregorianDate(gregorian_year, MonthOfYear.MARCH, 30).toordinal())))
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)
def toordinal(self): """Return ordinal date equivalent to Observational Hebrew date.""" year1 = self.year - 1 if self.month >= HebrewMonth.TISHRI else self.year start = HebrewDate(year1, HebrewMonth.NISAN, 1).toordinal() g_year = GregorianDate.to_year(start + 60) new_year = self.new_year(g_year) midmonth = new_year + int(round(29.5 * (self.month - 1))) + 15 return JAFFA.phasis_on_or_before(midmonth) + self.day - 1
def omer(cls, ordinal): """Return the number of elapsed weeks and days in the omer at date ordinal. Throws ValueError if that date does not fall during the omer.""" c = ordinal - cls.passover(GregorianDate.to_year(ordinal)) if 1 <= c <= 49: return [int(math.floor(c, 7)), c % 7] else: raise ValueError("Date does not fall within omer")
def new_year(cls, gregorian_year): """Return ordinal date of Observational (classical) Nisan 1 occurring in Gregorian year, 'gregorian_year'.""" jan1 = GregorianDate.new_year(gregorian_year) equinox = solar_longitude_after(Season.SPRING, jan1) sset = JAFFA.universal_from_standard( JAFFA.sunset(int(math.floor(equinox)))) return cls.phasis_on_or_after( int(math.floor(equinox)) - (14 if (equinox < sset) else 13), JAFFA)
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 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 fromordinal(cls, ordinal): """Return the ISO date corresponding to the ordinal date 'ordinal'.""" approx = GregorianDate.to_year(ordinal - 3) year = (approx + 1 if ordinal >= IsoDate(approx + 1, 1, 1).toordinal() else approx) week = 1 + int( math.floor(ordinal - IsoDate(year, 1, 1).toordinal() / 7)) day = amod(ordinal, 7) return IsoDate(year, week, day)
def hindu_lunar_new_year(g_year): """Return the ordinal 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 = int(math.floor(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 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 Observational Hebrew date (year month day) corresponding to ordinal date, 'ordinal'.""" crescent = JAFFA.phasis_on_or_before(ordinal) g_year = GregorianDate.to_year(ordinal) ny = cls.new_year(g_year) new_year = cls.new_year(g_year - 1) if (ordinal < ny) else ny month = int(round((crescent - new_year) / 29.5)) + 1 year = HebrewDate.fromordinal(new_year).year + ( 1 if month >= HebrewMonth.TISHRI else 0) day = ordinal - crescent + 1 return HebrewObservationalDate(year, month, day)
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)
def yom_ha_zikkaron(cls, gregorian_year): """Return ordinal date of Yom ha_Zikkaron occurring in Gregorian year 'gregorian_year'.""" hebrew_year = gregorian_year - GregorianDate.to_year(cls.EPOCH) iyyar4 = HebrewDate(hebrew_year, HebrewMonth.IYYAR, 4).toordinal() if weekday_fromordinal(iyyar4) in (DayOfWeek.THURSDAY, DayOfWeek.FRIDAY): return before_weekday(iyyar4, DayOfWeek.WEDNESDAY) elif DayOfWeek.SUNDAY == weekday_fromordinal(iyyar4): return iyyar4 + 1 else: return iyyar4