# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000 Donald N. Allingham # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # "Support for the dates" import re import string import intl _ = intl.gettext #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- class Date: formatCode = 0 BadFormat = _("Unknown Format") fmt = re.compile("\s*(from|between|bet)(.+)(and|to)(.+)\s*$", re.IGNORECASE) def __init__(self): self.start = SingleDate() self.stop = SingleDate() self.range = 0 def get_start_date(self): return self.start def get_stop_date(self): return self.stop #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def set(self,text): match = Date.fmt.match(text) if match: matches = match.groups() self.start.set(matches[1]) self.stop.set(matches[3]) self.range = 1 else: self.start.set(text) self.range = 0 #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getDate(self): function = SingleDate.fmtFunc[Date.formatCode] if self.range: return "from " + function(self.start) + " to " + function(self.stop) else: return function(self.start) #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getSaveDate(self): if self.range: return "FROM " + self.start.getFmt3() + " TO " + self.stop.getFmt3() else: return self.start.getFmt3() #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def quick_set(self,text): match = Date.fmt.match(text) if match: matches = match.groups() self.start.set(matches[1]) self.stop.set(matches[3]) self.range = 1 else: self.start.quick_set(text) self.range = 0 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- class SingleDate: "Date handling" exact = 0 about = 1 before = 2 after = 3 entryCode = 0 mname = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] m2num = { "jan" : 0, "feb" : 1, "mar" : 2, "apr" : 3, "may" : 4, "jun" : 5, "jul" : 6, "aug" : 7, "sep" : 8, "oct" : 9, "nov" : 10,"dec" : 11 } m2v = { "abt" : about , "about" : about, "est" : about , "circa" : about, "around": about, "before": before, "bef" : before, "after" : after, "aft" : after } modifiers = "(abt|about|est|circa|around|before|after|aft|bef)" start = "^\s*" + modifiers + "?\s*" fmt1 = re.compile(start + "(\S+)(\s+\d+\s*,)?\s*(\d+)?\s*$", re.IGNORECASE) fmt2 = re.compile(start + "(\d+)\s+(\S+)(\s+\d+)?\s*$", re.IGNORECASE) quick= re.compile(start + "(\d+)\s(\S\S\S)\s(\d+)", re.IGNORECASE) fmt3 = re.compile(start + "(\d+)\s*[./-]\s*(\d+)\s*[./-]\s*(\d+)\s*$", re.IGNORECASE) fmt4 = re.compile(start + "(\S+)\s+(\d+)\s*$", re.IGNORECASE) fmt5 = re.compile(start + "(\d+)\s*$", re.IGNORECASE) fmt6 = re.compile(start + "(\S+)\s*$", re.IGNORECASE) #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def __init__(self): self.month = -1 self.day = -1 self.year = -1 self.mode = SingleDate.exact #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def __cmp__(self,other): if self.year != other.year: return cmp(self.year,other.year) elif self.month != other.month: return cmp(self.month,other.month) elif self.day != other.day: return cmp(self.day,other.day) elif self.mode != other.mode: if self.mode == SingleDate.exact: return -1 else: return 1 else: return 0 #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def setMode(self,val): if val == None: self.mode = SingleDate.exact else: val = string.lower(val) self.mode = SingleDate.m2v[val] #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def setMonth(self,val): if val > 0 and val < 13: self.month = val - 1 else: self.month = -1 #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getMonth(self): return self.month + 1 #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def setDay(self,val): if val > 0 or val < 32: self.day = val #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getDay(self): return self.day #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def setYear(self,val): self.year = val #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getYear(self): return self.year #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def setMonthStr(self,text): if SingleDate.m2num.has_key(string.lower(text[0:3])): self.month = SingleDate.m2num[string.lower(text[0:3])] else: self.month = -1 #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getMonthStr(self): return SingleDate.mname[self.month] #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getSaveDate(self): return self.getFmt3() #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt1(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.year == -1: retval = SingleDate.mname[self.month] else: retval = "%s %d" % (SingleDate.mname[self.month],self.year) elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: month = SingleDate.mname[self.month] if self.year == -1: retval = "%s %d, ????" % (month,self.day) else: retval = "%s %d, %d" % (month,self.day,self.year) elif self.mode == SingleDate.about: month = SingleDate.mname[self.month] if self.year == -1: retval = "about %s %d, ????" % (month,self.day) else: retval = "about %s %d, %d" % (month,self.day,self.year) if self.mode == SingleDate.before: retval = "before " + retval elif self.mode == SingleDate.after: retval = "after " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt2(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.year == -1: month = SingleDate.mname[self.month] retval = string.upper(month[0:3]) else: month = SingleDate.mname[self.month] retval = "%s %d" % (string.upper(month[0:3]),self.year) elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: month = SingleDate.mname[self.month] if self.year == -1: retval = "%s %d, ????" % (string.upper(month[0:3]),self.day) else: retval = "%s %d, %d" % (string.upper(month[0:3]),self.day,self.year) elif self.mode == SingleDate.about: month = SingleDate.mname[self.month] if self.year == -1: retval = "ABT %s %s, ????" % (string.upper(month[0:3]),self.day) else: retval = "ABT %s %s, ????" % (string.upper(month[0:3]),self.day,self.year) if self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt3(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.year == -1: month = SingleDate.mname[self.month] retval = string.upper(month[0:3]) else: month = SingleDate.mname[self.month] retval = "%s %d" % (string.upper(month[0:3]),self.year) elif self.month == -1: retval = "%d" % self.year else: month = SingleDate.mname[self.month] if self.year == -1: retval = "%d %s ????" % (self.day,string.upper(month[0:3])) else: retval = "%d %s %d" % (self.day,string.upper(month[0:3]),self.year) if self.mode == SingleDate.about: retval = "ABT " + retval elif self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt4(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: if year == -1: retval = "%d/%d/????" % (self.month+1,self.day) else: retval = "%d/%d/%d" % (self.month+1,self.day,self.year) elif self.mode == SingleDate.about: if year == -1: retval = "ABT %d/%d/????" % (self.month+1,self.day,self.year) else: retval = "ABT %d/%d/%d" % (self.month+1,self.day,self.year) if self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt5(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: if self.year == -1: retval = "%d-%d-????" % (self.month+1,self.day) else: retval = "%d-%d-%d" % (self.month+1,self.day,self.year) elif self.mode == SingleDate.about: if self.year == -1: retval = "ABT %d-%d-????" % (self.month+1,self.day,self.year) else: retval = "ABT %d-%d-%d" % (self.month+1,self.day,self.year) if self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt6(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: if self.year == -1: retval = "%d/%d/????" % (self.day,self.month+1) else: retval = "%d/%d/%d" % (self.day,self.month+1,self.year) elif self.mode == SingleDate.about: if self.year == -1: retval = "ABT %d/%d/????" % (self.day,self.month+1) else: retval = "ABT %d/%d/%d" % (self.day,self.month+1,self.year) if self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getFmt7(self): retval = "" if self.month == -1 and self.day == -1 and self.year == -1 : pass elif self.day == -1: if self.month == -1: retval = "%d" % self.year elif self.month == -1: retval = "%d" % self.year elif self.mode == SingleDate.exact: if self.year == -1: retval = "%d-%d-????" % (self.day,self.month+1) else: retval = "%d-%d-%d" % (self.day,self.month+1,self.year) elif self.mode == SingleDate.about: if self.year == -1: retval = "ABT %d-%d-????" % (self.day,self.month+1) else: retval = "ABT %d-%d-%d" % (self.day,self.month+1,self.year) if self.mode == SingleDate.before: retval = "BEFORE " + retval elif self.mode == SingleDate.after: retval = "AFTER " + retval return retval #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- fmtFunc = [ getFmt1, getFmt2, getFmt3, getFmt4, getFmt5, getFmt6, getFmt7 ] #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getDate(self): function = SingleDate.fmtFunc[Date.formatCode] return function(self) #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def getMode(self,val): if val == None: self.mode = SingleDate.exact elif string.lower(val)[0:3] == "bef": self.mode = SingleDate.before elif string.lower(val)[0:3] == "aft": self.mode = SingleDate.after else: self.mode = SingleDate.about #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def set(self,text): match = SingleDate.fmt2.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) self.setMonthStr(matches[2]) self.setDay(string.atoi(matches[1])) if len(matches) == 4: val = matches[3] if val == None or val[0] == '?': self.setYear(-1) else: self.setYear(string.atoi(val)) else: self.setYear(-1) return 1 match = SingleDate.fmt1.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) self.setMonthStr(matches[1]) val = matches[2] if val: self.setDay(string.atoi(string.replace(val,',',''))) else: self.setDay(-1) if len(matches) == 4: val = matches[3] if val == None or val[0] == '?': self.setYear(-1) else: self.setYear(string.atoi(val)) else: self.setYear(-1) return 1 match = SingleDate.fmt3.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) if SingleDate.entryCode == 0: self.setMonth(string.atoi(matches[1])) self.setDay(string.atoi(matches[2])) else: self.setMonth(string.atoi(matches[2])) self.setDay(string.atoi(matches[1])) if len(matches) == 3: val = matches[3] if val == None or val[0] == '?': self.setYear(-1) else: self.setYear(string.atoi(val)) else: self.setYear(-1) return 1 match = SingleDate.fmt5.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) self.setMonth(-1) self.setDay(-1) self.setYear(string.atoi(matches[1])) return 1 match = SingleDate.fmt4.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) self.setMonthStr(matches[1]) self.setDay(-1) if len(matches) == 4: val = matches[3] if val == None or val[0] == '?' : self.setYear(-1) else: self.setYear(string.atoi(val)) return 1 match = SingleDate.fmt6.match(text) if match != None: matches = match.groups() self.getMode(matches[0]) self.setMonth(matches[1]) self.setDay(-1) self.setYear(-1) return 1 raise Date.BadFormat,text #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def quick_set(self,text): match = SingleDate.quick.match(text) if match != None: matches = match.groups() self.setMode(matches[0]) self.setMonthStr(matches[2]) self.setDay(string.atoi(matches[1])) if len(matches) == 4: val = matches[3] if val == None or val[0] == '?': self.setYear(-1) else: self.setYear(string.atoi(val)) else: self.setYear(-1) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def compare_dates(f,s): first = f.get_start_date() second = s.get_start_date() if first.year != second.year: return cmp(first.year,second.year) elif first.month != second.month: return cmp(first.month,second.month) else: return cmp(first.day,second.day)