Gnumed.timelinelib.calendar.pharaonic.pharaonic

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

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

      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  from timelinelib.calendar.pharaonic.time import PharaonicDelta
     19  from timelinelib.calendar.pharaonic.time import PharaonicTime
     20
     21
     22  FIRST_DAY = 1448638
     23
     24
     25 -class PharaonicDateTime(object):
     26
     27 -    def __init__(self, year, month, day, hour, minute, second):
     28          if not is_valid(year, month, day):
     29              raise ValueError("Invalid pharaonic date %s-%s-%s" % (year, month, day))
     30          self.year = year
     31          self.month = month
     32          self.day = day
     33          self.hour = hour
     34          self.minute = minute
     35          self.second = second
     36
     37 -    def __eq__(self, other):
     38          return (isinstance(other, self.__class__) and
     39                  self.to_tuple() == other.to_tuple())
     40
     41 -    def __ne__(self, other):
     42          return not (self == other)
     43
     44      @classmethod
     45 -    def from_ymd(cls, year, month, day):
     46          return cls(year, month, day, 0, 0, 0)
     47
     48      @classmethod
     49 -    def from_time(cls, time):
     50          (year, month, day) = julian_day_to_pharaonic_ymd(time.julian_day)
     51          (hour, minute, second) = time.get_time_of_day()
     52          return cls(year, month, day, hour, minute, second)
     53
     54      # the 13th month is considered "inbetween" years so it returns a week number 0
     55      @property
     56 -    def week_number(self):
     57
     58          if self.month == 13:
     59              return 0
     60
     61          length_of_week = 10
     62          days_into_year = ((self.month - 1)*30) + self.day
     63
     64          if self.day % length_of_week > 0:
     65              return (days_into_year // length_of_week) + 1
     66
     67          return days_into_year // length_of_week
     68
     69 -    def is_bc(self):
     70          return self.year <= 0
     71
     72 -    def replace(self, year=None, month=None):
     73          if year is None:
     74              year = self.year
     75          if month is None:
     76              month = self.month
     77          return self.__class__(
     78              year,
     79              month,
     80              self.day,
     81              self.hour,
     82              self.minute,
     83              self.second
     84          )
     85
     86 -    def days_in_month(self):
     87          return days_in_month(self.year, self.month)
     88
     89 -    def to_tuple(self):
     90          return (self.year, self.month, self.day, self.hour, self.minute,
     91                  self.second)
     92
     93 -    def to_date_tuple(self):
     94          return self.year, self.month, self.day
     95
     96 -    def to_time_tuple(self):
     97          return self.hour, self.minute, self.second
     98
     99 -    def to_time(self):
    100          days = pharaonic_ymd_to_julian_day(self.year, self.month, self.day)
    101          seconds = self.hour * 60 * 60 + self.minute * 60 + self.second
    102          return PharaonicTime(days, seconds)
    103
    104 -    def is_first_day_in_year(self):
    105          return (self.month == 1 and
    106                  self.day == 1 and
    107                  self.hour == 0 and
    108                  self.minute == 0 and
    109                  self.second == 0)
    110
    111 -    def is_first_of_month(self):
    112          return (self.day == 1 and
    113                  self.hour == 0 and
    114                  self.minute == 0 and
    115                  self.second == 0)
    116
    117 -    def __repr__(self):
    118          return "PharaonicDateTime<%d-%02d-%02d %02d:%02d:%02d>" % self.to_tuple()
    119
    120
    121 -def days_in_month(year, month):
    122      if month <= 12:
    123          return 30
    124      else:
    125          return 5
    126
    127
    128 -def is_valid_time(hour, minute, second):
    129      return (
    130          hour >= 0 and hour < 24 and
    131          minute >= 0 and minute < 60 and
    132          second >= 0 and second < 60
    133      )
    134
    135
    136 -def is_valid(year, month, day):
    137      return month >= 1 and month <= 13 and day >= 1 and day <= days_in_month(year, month)
    138
    139
    140 -def julian_day_to_pharaonic_ymd(julian_day):
    141      """
    142      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
    143      """
    144      if julian_day < PharaonicTime.MIN_JULIAN_DAY:
    145          raise ValueError("pharaonic_day_to_gregorian_ymd only works for julian days >= %d, but was %d" % (PharaonicTime.MIN_JULIAN_DAY, julian_day))
    146
    147      y = 3968
    148      j = 47
    149      m = 0
    150      n = 13
    151      r = 1
    152      p = 365
    153      q = 0
    154      v = 0
    155      u = 1
    156      s = 30
    157      t = 0
    158      w = 0
    159
    160      f = julian_day + j
    161      e = r * f + v
    162      g = (e % p)//r
    163      h = u * g + w
    164      day = ((h % s)//u) + 1
    165      month = (((h // s) + m) % n) + 1
    166      year = (e // p) - y + (n + m - month)//n
    167      return year, month, day
    168
    169
    170 -def pharaonic_ymd_to_julian_day(year, month, day):
    171      """
    172      Pharaonic year 1 = Julian day 1448638
    173      """
    174
    175      y = 3968
    176      j = 47
    177      m = 0
    178      n = 13
    179      r = 1
    180      p = 365
    181      q = 0
    182      v = 0
    183      u = 1
    184      s = 30
    185      t = 0
    186      w = 0
    187
    188      h = month - m
    189      g = year + y - (n-h)//n
    190      f = (h - 1 + n) % n
    191      e = (p * g + q)//r + day - 1 -j
    192      julian_day = e + (s * f + t)//u
    193
    194      if julian_day < PharaonicTime.MIN_JULIAN_DAY:
    195          raise ValueError("pharaonic_ymd_to_julian_day only works for julian days >= %d, but was %d" % (PharaonicTime.MIN_JULIAN_DAY, julian_day))
    196      return julian_day
    197