Gnumed.timelinelib.calendar.coptic.coptic

Package Gnumed :: Package timelinelib :: Package calendar :: Package coptic :: Module coptic |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.calendar.coptic.coptic

      1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
      2  #
      3  # This file is part of Timeline.
      4  #
      5  # Timeline is free software: you can redistribute it and/or modify
      6  # it under the terms of the GNU General Public License as published by
      7  # the Free Software Foundation, either version 3 of the License, or
      8  # (at your option) any later version.
      9  #
     10  # Timeline is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  # GNU General Public License for more details.
     14  #
     15  # You should have received a copy of the GNU General Public License
     16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>.
     17
     18
     19  from timelinelib.calendar.coptic.time import CopticDelta
     20  from timelinelib.calendar.coptic.time import CopticTime
     21
     22
     23  FIRST_DAY = 1825030
     24
     25
     26 -class CopticDateTime(object):
     27
     28 -    def __init__(self, year, month, day, hour, minute, second):
     29          if not is_valid(year, month, day):
     30              raise ValueError("Invalid coptic date %s-%s-%s" % (year, month, day))
     31          self.year = year
     32          self.month = month
     33          self.day = day
     34          self.hour = hour
     35          self.minute = minute
     36          self.second = second
     37
     38 -    def __eq__(self, other):
     39          return (isinstance(other, self.__class__) and
     40                  self.to_tuple() == other.to_tuple())
     41
     42 -    def __ne__(self, other):
     43          return not (self == other)
     44
     45      @classmethod
     46 -    def from_ymd(cls, year, month, day):
     47          return cls(year, month, day, 0, 0, 0)
     48
     49      @classmethod
     50 -    def from_time(cls, time):
     51          (year, month, day) = julian_day_to_coptic_ymd(time.julian_day)
     52          (hour, minute, second) = time.get_time_of_day()
     53          return cls(year, month, day, hour, minute, second)
     54
     55      @property
     56 -    def week_number(self):
     57          def tkyriaka_week_1(year):
     58              from timelinelib.calendar.coptic.timetype import CopticTimeType
     59              thoth_4 = CopticDateTime.from_ymd(year, 1, 4).to_time()
     60              thoth_4_day_of_week = CopticTimeType().get_day_of_week(thoth_4)
     61              return thoth_4 - CopticDelta.from_days(thoth_4_day_of_week)
     62
     63          def days_between(end, start):
     64              return end.julian_day - start.julian_day
     65
     66          def days_since_tkyriaka_week_1(time):
     67              year = CopticDateTime.from_time(time).year
     68              diff = days_between(end=time, start=tkyriaka_week_1(year + 1))
     69              if diff >= 0:
     70                  return diff
     71              diff = days_between(end=time, start=tkyriaka_week_1(year))
     72              if diff >= 0:
     73                  return diff
     74              diff = days_between(end=time, start=tkyriaka_week_1(year - 1))
     75              if diff >= 0:
     76                  return diff
     77              raise ValueError("should not end up here")
     78          # TODO: days_since_monday_week_1, unresolved!!!
     79          return days_since_monday_week_1(self.to_time()) // 7 + 1
     80      """
     81          if self.month == 13:
     82              return 0
     83
     84          length_of_week = 10
     85          days_into_year = ((self.month - 1)*30) + self.day
     86
     87          if self.day % length_of_week > 0:
     88              return (days_into_year / length_of_week) + 1
     89
     90          return days_into_year / length_of_week
     91          """
     92
     93 -    def is_bc(self):
     94          return self.year <= 0
     95
     96 -    def replace(self, year=None, month=None):
     97          if year is None:
     98              year = self.year
     99          if month is None:
    100              month = self.month
    101          return self.__class__(
    102              year,
    103              month,
    104              self.day,
    105              self.hour,
    106              self.minute,
    107              self.second
    108          )
    109
    110 -    def days_in_month(self):
    111          return days_in_month(self.year, self.month)
    112
    113 -    def to_tuple(self):
    114          return (self.year, self.month, self.day, self.hour, self.minute,
    115                  self.second)
    116
    117 -    def to_date_tuple(self):
    118          return self.year, self.month, self.day
    119
    120 -    def to_time_tuple(self):
    121          return self.hour, self.minute, self.second
    122
    123 -    def to_time(self):
    124          days = coptic_ymd_to_julian_day(self.year, self.month, self.day)
    125          seconds = self.hour * 60 * 60 + self.minute * 60 + self.second
    126          return CopticTime(days, seconds)
    127
    128 -    def is_first_day_in_year(self):
    129          return (self.month == 1 and
    130                  self.day == 1 and
    131                  self.hour == 0 and
    132                  self.minute == 0 and
    133                  self.second == 0)
    134
    135 -    def is_first_of_month(self):
    136          return (self.day == 1 and
    137                  self.hour == 0 and
    138                  self.minute == 0 and
    139                  self.second == 0)
    140
    141 -    def __repr__(self):
    142          return "CopticDateTime<%d-%02d-%02d %02d:%02d:%02d>" % self.to_tuple()
    143
    144
    145 -def days_in_month(year, month):
    146      if month <= 12:
    147          return 30
    148      elif is_leap_year(year):
    149          return 6
    150      else:
    151          return 5
    152
    153
    154 -def is_leap_year(year):
    155      if year > 0 and (year+1) % 4 == 0:
    156          return True
    157      elif year < 0 and year % 4 == 0:
    158          return True
    159      else:
    160          return False
    161
    162
    163 -def num_leap_years(year):
    164      return int(abs(year//4))
    165
    166
    167 -def is_valid_time(hour, minute, second):
    168      return (
    169          hour >= 0 and hour < 24 and
    170          minute >= 0 and minute < 60 and
    171          second >= 0 and second < 60
    172      )
    173
    174
    175 -def is_valid(year, month, day):
    176      return month >= 1 and month <= 13 and day >= 1 and day <= days_in_month(year, month)
    177
    178
    179 -def julian_day_to_coptic_ymd(julian_day):
    180      """
    181      This calendar calculation was originally published in Explanatory Supplement to the Astronomical Almanac, S.E. Urban and P.K. Seidelman, Eds. (2012). You can purchase the book at uscibooks.com/urban.htm. "15.11 Calendar Conversion Algorithms" from the following pdf is used in the below code. https://aa.usno.navy.mil/publications/docs/c15_usb_online.pdf
    182      """
    183      if julian_day < CopticTime.MIN_JULIAN_DAY:
    184          raise ValueError("coptic_day_to_gregorian_ymd only works for julian days >= %d, but was %d" % (CopticTime.MIN_JULIAN_DAY, julian_day))
    185      # year_inx = int((julian_day - FIRST_DAY) / 365)
    186      # days_inx = (julian_day - FIRST_DAY) - year_inx * 365
    187      # month_inx = days_inx / 30
    188      # day_inx = days_inx - month_inx * 30
    189
    190      y = 4996
    191      j = 124
    192      m = 0
    193      n = 13
    194      r = 4
    195      p = 1461
    196      q = 0
    197      v = 3
    198      u = 1
    199      s = 30
    200      t = 0
    201      w = 0
    202
    203      f = julian_day + j
    204      e = r * f + v
    205      g = (e % p)//r
    206      h = u * g + w
    207      day = ((h % s)//u) + 1
    208      month = (((h // s) + m) % n) + 1
    209      year = (e // p) - y + (n + m - month)//n
    210      return year, month, day
    211      # return (year_inx + 1, month_inx + 1, day_inx + 1)
    212
    213
    214 -def coptic_ymd_to_julian_day(year, month, day):
    215      """
    216      Coptic year 1 = Julian day 1825030
    217      """
    218      # julian_day = FIRST_DAY + (year - 1) * 365 + (month - 1) * 30 + (day - 1)
    219      # num_leap_days = num_leap_years(year)
    220      # julian_day = FIRST_DAY + (year - 1 - num_leap_days)*365 + num_leap_days*366 + (month - 1)*30 + (day - 1)
    221
    222      y = 4996
    223      j = 124
    224      m = 0
    225      n = 13
    226      r = 4
    227      p = 1461
    228      q = 0
    229      v = 3
    230      u = 1
    231      s = 30
    232      t = 0
    233      w = 0
    234
    235      h = month - m
    236      g = year + y - (n-h)//n
    237      f = (h - 1 + n) % n
    238      e = (p * g + q)//r + day - 1 -j
    239      julian_day = e + (s * f + t)//u
    240
    241      if julian_day < CopticTime.MIN_JULIAN_DAY:
    242          raise ValueError("coptic_ymd_to_julian_day only works for julian days >= %d, but was %d" % (CopticTime.MIN_JULIAN_DAY, julian_day))
    243      return julian_day
    244