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

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