Package RelLib :: Module _Date
[frames] | no frames]

Source Code for Module RelLib._Date

  1  # 
  2  # Gramps - a GTK+/GNOME based genealogy program 
  3  # 
  4  # Copyright (C) 2000-2006  Donald N. Allingham 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful,  
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19  # 
 20   
 21  # $Id: _Date.py 7306 2006-09-09 17:10:13Z dallingham $ 
 22   
 23  "Support for dates" 
 24   
 25  __author__ = "Donald N. Allingham" 
 26  __revision__ = "$Revision: 7306 $" 
 27   
 28  from gettext import gettext as _ 
 29  from _CalSdn import * 
 30   
 31  #------------------------------------------------------------------------- 
 32  # 
 33  # DateError exception 
 34  # 
 35  #------------------------------------------------------------------------- 
36 -class DateError(Exception):
37 """Error used to report Date errors"""
38 - def __init__(self, value=""):
39 Exception.__init__(self) 40 self.value = value
41
42 - def __str__(self):
43 return self.value
44 45 #------------------------------------------------------------------------- 46 # 47 # Date class 48 # 49 #-------------------------------------------------------------------------
50 -class Date:
51 """ 52 The core date handling class for GRAMPs. Supports partial dates, 53 compound dates and alternate calendars. 54 """ 55 56 MOD_NONE = 0 57 MOD_BEFORE = 1 58 MOD_AFTER = 2 59 MOD_ABOUT = 3 60 MOD_RANGE = 4 61 MOD_SPAN = 5 62 MOD_TEXTONLY = 6 63 64 QUAL_NONE = 0 65 QUAL_ESTIMATED = 1 66 QUAL_CALCULATED = 2 67 68 CAL_GREGORIAN = 0 69 CAL_JULIAN = 1 70 CAL_HEBREW = 2 71 CAL_FRENCH = 3 72 CAL_PERSIAN = 4 73 CAL_ISLAMIC = 5 74 75 EMPTY = (0, 0, 0, False) 76 77 _POS_DAY = 0 78 _POS_MON = 1 79 _POS_YR = 2 80 _POS_SL = 3 81 _POS_RDAY = 4 82 _POS_RMON = 5 83 _POS_RYR = 6 84 _POS_RSL = 7 85 86 _calendar_convert = [ 87 gregorian_sdn, 88 julian_sdn, 89 hebrew_sdn, 90 french_sdn, 91 persian_sdn, 92 islamic_sdn, 93 ] 94 95 _calendar_change = [ 96 gregorian_ymd, 97 julian_ymd, 98 hebrew_ymd, 99 french_ymd, 100 persian_ymd, 101 islamic_ymd, 102 ] 103 104 calendar_names = ["Gregorian", 105 "Julian", 106 "Hebrew", 107 "French Republican", 108 "Persian", 109 "Islamic"] 110 111 112 ui_calendar_names = [_("Gregorian"), 113 _("Julian"), 114 _("Hebrew"), 115 _("French Republican"), 116 _("Persian"), 117 _("Islamic")] 118
119 - def __init__(self, source=None):
120 """ 121 Creates a new Date instance. 122 """ 123 if source: 124 self.calendar = source.calendar 125 self.modifier = source.modifier 126 self.quality = source.quality 127 self.dateval = source.dateval 128 self.text = source.text 129 self.sortval = source.sortval 130 else: 131 self.calendar = Date.CAL_GREGORIAN 132 self.modifier = Date.MOD_NONE 133 self.quality = Date.QUAL_NONE 134 self.dateval = Date.EMPTY 135 self.text = u"" 136 self.sortval = 0
137
138 - def serialize(self, no_text_date=False):
139 """ 140 Convert to a series of tuples for data storage 141 """ 142 if no_text_date: 143 text = u'' 144 else: 145 text = self.text 146 147 return (self.calendar, self.modifier, self.quality, 148 self.dateval, text, self.sortval)
149
150 - def unserialize(self, data):
151 """ 152 Load from the format created by serialize 153 """ 154 (self.calendar, self.modifier, self.quality, 155 self.dateval, self.text, self.sortval) = data 156 return self
157
158 - def copy(self, source):
159 """ 160 Copy all the attributes of the given Date instance 161 to the present instance, without creating a new object. 162 """ 163 self.calendar = source.calendar 164 self.modifier = source.modifier 165 self.quality = source.quality 166 self.dateval = source.dateval 167 self.text = source.text 168 self.sortval = source.sortval
169
170 - def __cmp__(self, other):
171 """ 172 Comparison function. Allows the usage of equality tests. 173 This allows you do run statements like 'date1 <= date2' 174 """ 175 if isinstance(other, Date): 176 return cmp(self.sortval, other.sortval) 177 else: 178 return -1
179
180 - def is_equal(self, other):
181 """ 182 Return 1 if the given Date instance is the same as the present 183 instance IN ALL REGARDS. Needed, because the __cmp__ only looks 184 at the sorting value, and ignores the modifiers/comments. 185 """ 186 if self.modifier == other.modifier \ 187 and self.modifier == Date.MOD_TEXTONLY: 188 value = self.text == other.text 189 else: 190 value = (self.calendar == other.calendar and 191 self.modifier == other.modifier and 192 self.quality == other.quality and 193 self.dateval == other.dateval) 194 return value
195
196 - def __str__(self):
197 """ 198 Produces a string representation of the Date object. If the 199 date is not valid, the text representation is displayed. If 200 the date is a range or a span, a string in the form of 201 'YYYY-MM-DD - YYYY-MM-DD' is returned. Otherwise, a string in 202 the form of 'YYYY-MM-DD' is returned. 203 """ 204 if self.quality == Date.QUAL_ESTIMATED: 205 qual = "est " 206 elif self.quality == Date.QUAL_CALCULATED: 207 qual = "calc " 208 else: 209 qual = "" 210 211 if self.modifier == Date.MOD_BEFORE: 212 pref = "bef " 213 elif self.modifier == Date.MOD_AFTER: 214 pref = "aft " 215 elif self.modifier == Date.MOD_ABOUT: 216 pref = "abt " 217 else: 218 pref = "" 219 220 if self.calendar != Date.CAL_GREGORIAN: 221 cal = " (%s)" % Date.calendar_names[self.calendar] 222 else: 223 cal = "" 224 225 if self.modifier == Date.MOD_TEXTONLY: 226 val = self.text 227 elif self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN: 228 val = "%04d-%02d-%02d - %04d-%02d-%02d" % ( 229 self.dateval[Date._POS_YR], self.dateval[Date._POS_MON], 230 self.dateval[Date._POS_DAY], self.dateval[Date._POS_RYR], 231 self.dateval[Date._POS_RMON], self.dateval[Date._POS_RDAY]) 232 else: 233 val = "%04d-%02d-%02d" % ( 234 self.dateval[Date._POS_YR], self.dateval[Date._POS_MON], 235 self.dateval[Date._POS_DAY]) 236 return "%s%s%s%s" % (qual, pref, val, cal)
237
238 - def get_sort_value(self):
239 """ 240 Returns the sort value of Date object. If the value is a 241 text string, 0 is returned. Otherwise, the calculated sort 242 date is returned. The sort date is rebuilt on every assignment. 243 244 The sort value is an integer representing the value. A date of 245 March 5, 1990 would have the value of 19900305. 246 """ 247 return self.sortval
248
249 - def get_modifier(self):
250 """ 251 Returns an integer indicating the calendar selected. The valid 252 values are:: 253 254 MOD_NONE = no modifier (default) 255 MOD_BEFORE = before 256 MOD_AFTER = after 257 MOD_ABOUT = about 258 MOD_RANGE = date range 259 MOD_SPAN = date span 260 MOD_TEXTONLY = text only 261 """ 262 return self.modifier
263
264 - def set_modifier(self, val):
265 """ 266 Sets the modifier for the date. 267 """ 268 if val not in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, 269 Date.MOD_ABOUT, Date.MOD_RANGE, Date.MOD_SPAN, 270 Date.MOD_TEXTONLY): 271 raise DateError("Invalid modifier") 272 self.modifier = val
273
274 - def get_quality(self):
275 """ 276 Returns an integer indicating the calendar selected. The valid 277 values are:: 278 279 QUAL_NONE = normal (default) 280 QUAL_ESTIMATED = estimated 281 QUAL_CALCULATED = calculated 282 """ 283 return self.quality
284
285 - def set_quality(self, val):
286 """ 287 Sets the quality selected for the date. 288 """ 289 if val not in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, 290 Date.QUAL_CALCULATED): 291 raise DateError("Invalid quality") 292 self.quality = val
293
294 - def get_calendar(self):
295 """ 296 Returns an integer indicating the calendar selected. The valid 297 values are:: 298 299 CAL_GREGORIAN - Gregorian calendar 300 CAL_JULIAN - Julian calendar 301 CAL_HEBREW - Hebrew (Jewish) calendar 302 CAL_FRENCH - French Republican calendar 303 CAL_PERSIAN - Persian calendar 304 CAL_ISLAMIC - Islamic calendar 305 """ 306 return self.calendar
307
308 - def set_calendar(self, val):
309 """ 310 Sets the calendar selected for the date. 311 """ 312 if val not in (Date.CAL_GREGORIAN, Date.CAL_JULIAN, Date.CAL_HEBREW, 313 Date.CAL_FRENCH, Date.CAL_PERSIAN, Date.CAL_ISLAMIC): 314 raise DateError("Invalid calendar") 315 self.calendar = val
316
317 - def get_start_date(self):
318 """ 319 Returns a tuple representing the start date. If the date is a 320 compound date (range or a span), it is the first part of the 321 compound date. If the date is a text string, a tuple of 322 (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash) 323 is returned. If slash is True, then the date is in the form of 1530/1. 324 """ 325 if self.modifier == Date.MOD_TEXTONLY: 326 val = Date.EMPTY 327 else: 328 val = self.dateval[0:4] 329 return val
330
331 - def get_stop_date(self):
332 """ 333 Returns a tuple representing the second half of a compound date. 334 If the date is not a compound date, (including text strings) a tuple 335 of (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash) 336 is returned. If slash is True, then the date is in the form of 1530/1. 337 """ 338 if self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN: 339 val = self.dateval[4:8] 340 else: 341 val = Date.EMPTY 342 return val
343
344 - def _get_low_item(self, index):
345 """ 346 Returns the item specified 347 """ 348 if self.modifier == Date.