Gnumed.timelinelib.calendar.pharaonic.dateformatter

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

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

      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.pharaonic.pharaonic import days_in_month
     20  from timelinelib.calendar.pharaonic.monthnames import abbreviated_name_of_month
     21  from timelinelib.calendar.pharaonic.monthnames import month_of_abbreviated_name
     22
     23
     24 -class PharaonicDateFormatter(object):
     25
     26      YEAR = "YEAR"
     27      MONTH = "MONTH"
     28      DAY = "DAY"
     29
     30 -    def __init__(self):
     31          self.set_separators("-", "-")
     32          self.set_region_order(year=0, month=1, day=2)
     33          self.use_abbreviated_name_for_month(False)
     34          self.use_date_default_values = False
     35          self.default_year = '1700'
     36          self.default_month = '01'
     37          self.default_day = '01'
     38
     39 -    def use_abbreviated_name_for_month(self, value):
     40          self._use_abbreviated_name_for_month = value
     41
     42 -    def set_separators(self, first, second):
     43          if not first or not second:
     44              raise ValueError("Can not set empty separator.")
     45          self._first_separator = first
     46          self._second_separator = second
     47
     48 -    def set_region_order(self, year, month, day):
     49          if set([year, month, day]) != set([0, 1, 2]):
     50              raise ValueError("Invalid region order. Must be a combination of 0, 1, and 2.")
     51          self._year_position = year
     52          self._month_position = month
     53          self._day_position = day
     54
     55 -    def set_defaults(self, use_date_default_values, default_year=None, default_month=None, default_day=None):
     56          self.use_date_default_values = use_date_default_values
     57          self.default_year = default_year
     58          self.default_month = default_month
     59          self.default_day = default_day
     60
     61 -    def format(self, ymd_tuple):
     62          (year, month, day) = ymd_tuple
     63          return (self._format_date(year, month, day), self._is_bc(year))
     64
     65 -    def parse(self, date_bc_tuple):
     66          (date, is_bc) = date_bc_tuple
     67          regions = self._split(date)
     68          if self.use_date_default_values:
     69              self.set_default_regions(regions, date)
     70          year = self._parse_year(regions[self._year_position], is_bc)
     71          month = self._parse_month(regions[self._month_position])
     72          day = self._parse_day(regions[self._day_position], year, month)
     73          return (year, month, day)
     74
     75 -    def set_default_regions(self, regions, date):
     76          if regions == ['', '', '']:
     77              regions[0] = date
     78          for n in range(3):
     79              if regions[n] == '':
     80                  self.set_default_for_region(regions, n)
     81
     82 -    def set_default_for_region(self, regions, n):
     83          if self._year_position == n:
     84              regions[n] = self.default_year
     85          elif self._month_position == n:
     86              regions[n] = self.default_month
     87          elif self._day_position == n:
     88              regions[n] = self.default_day
     89
     90 -    def get_region_type(self, date_string, cursor_position):
     91          return {
     92              self._year_position: self.YEAR,
     93              self._month_position: self.MONTH,
     94              self._day_position: self.DAY,
     95          }[self._get_region(date_string, cursor_position)]
     96
     97 -    def _get_region(self, date_string, cursor_position):
     98          if cursor_position < self._get_region_start(date_string, 1):
     99              return 0
    100          elif cursor_position < self._get_region_start(date_string, 2):
    101              return 1
    102          else:
    103              return 2
    104
    105 -    def _split(self, date_string):
    106          region_1 = region_2 = region_3 = ''
    107          try:
    108              (region_1, region_2) = date_string.split(self._first_separator, 1)
    109              (region_2, region_3) = region_2.split(self._second_separator, 1)
    110          except ValueError:
    111              pass
    112          return [
    113              region_1,
    114              region_2,
    115              region_3,
    116          ]
    117
    118 -    def get_next_region(self, date_string, cursor_position):
    119          if self._cursor_at_end_of_string(date_string, cursor_position):
    120              return None
    121          for region in [1, 2]:
    122              if cursor_position < self._get_region_start(date_string, region):
    123                  return self._get_region_selection(date_string, region)
    124          return None
    125
    126 -    def _cursor_at_end_of_string(self, date_string, cursor_position):
    127          return cursor_position == len(date_string)
    128
    129 -    def get_previous_region(self, date_string, cursor_position):
    130          for region in [1, 0]:
    131              if cursor_position > self._get_region_end(date_string, region):
    132                  return self._get_region_selection(date_string, region)
    133          return None
    134
    135 -    def _get_region_selection(self, date_string, which_region):
    136          return (self._get_region_start(date_string, which_region),
    137                  self._get_region_len(date_string, which_region))
    138
    139 -    def _get_region_len(self, date_string, which_region):
    140          return len(self._split(date_string)[which_region])
    141
    142 -    def _get_region_start(self, date_string, which_region):
    143          part_delimiter = {
    144              0: 0,
    145              1: 2,
    146              2: 4,
    147          }[which_region]
    148          return len("".join(self._get_all_parts(date_string)[:part_delimiter]))
    149
    150 -    def _get_region_end(self, date_string, which_region):
    151          part_delimiter = {
    152              0: 1,
    153              1: 3,
    154              2: 5,
    155          }[which_region]
    156          return len("".join(self._get_all_parts(date_string)[:part_delimiter]))
    157
    158 -    def _get_all_parts(self, date_string):
    159          regions = self._split(date_string)
    160          return [
    161              regions[0],
    162              self._first_separator,
    163              regions[1],
    164              self._second_separator,
    165              regions[2],
    166          ]
    167
    168 -    def _format_date(self, year, month, day):
    169          regions = {
    170              self._year_position: self._format_year(year),
    171              self._month_position: self._format_month(month),
    172              self._day_position: self._format_day(day),
    173          }
    174          return "".join([
    175              regions[0],
    176              self._first_separator,
    177              regions[1],
    178              self._second_separator,
    179              regions[2],
    180          ])
    181
    182 -    def _format_year(self, year):
    183          if self._is_bc(year):
    184              new_year = 1 - year
    185          else:
    186              new_year = year
    187          return "%04d" % new_year
    188
    189 -    def _is_bc(self, year):
    190          return year <= 0
    191
    192 -    def _parse_year(self, year_string, is_bc):
    193          if is_bc:
    194              return 1 - int(year_string)
    195          else:
    196              return int(year_string)
    197
    198 -    def _format_month(self, month):
    199          if self._use_abbreviated_name_for_month:
    200              return abbreviated_name_of_month(month)
    201          else:
    202              return "%02d" % month
    203
    204 -    def _parse_month(self, month_string):
    205          if self._use_abbreviated_name_for_month:
    206              return month_of_abbreviated_name(month_string)
    207          else:
    208              month = int(month_string)
    209              if month - 1 in range(12):
    210                  return month
    211              else:
    212                  raise ValueError("Invalid month")
    213
    214 -    def _format_day(self, day):
    215          return "%02d" % day
    216
    217 -    def _parse_day(self, day_string, year, month):
    218          day = int(day_string)
    219          if day - 1 in range(days_in_month(year, month)):
    220              return day
    221          else:
    222              raise ValueError("Invalid day")
    223