diff --git a/src/Calendar.py b/src/Calendar.py index 57ffbf526..5fccb6543 100644 --- a/src/Calendar.py +++ b/src/Calendar.py @@ -30,53 +30,45 @@ __version__ = "$Revision$" import math from intl import gettext as _ -import Date - -_FR_SDN_OFFSET = 2375474 -_FR_DAYS_PER_4_YEARS = 1461 -_FR_DAYS_PER_MONTH = 30 -_FR_FIRST_VALID = 2375840 -_FR_LAST_VALID = 2380952 -_GR_SDN_OFFSET = 32045 -_GR_DAYS_PER_5_MONTHS = 153 -_GR_DAYS_PER_4_YEARS = 1461 -_GR_DAYS_PER_400_YEARS = 146097 -_J_SDN_OFFSET = 32083 -_J_DAYS_PER_5_MONTHS = 153 -_J_DAYS_PER_4_YEARS = 1461 - -_HALAKIM_PER_HOUR = 1080 -_HALAKIM_PER_DAY = 25920 -_HALAKIM_PER_LUNAR_CYCLE = ((29 * _HALAKIM_PER_DAY) + 13753) -_HALAKIM_PER_METONIC_CYCLE = (_HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7)) - -_H_SDN_OFFSET = 347997 -_NEW_MOON_OF_CREATION = 31524 - -_SUNDAY = 0 -_MONDAY = 1 -_TUESDAY = 2 -_WEDNESDAY= 3 -_FRIDAY = 5 - -_NOON = (18 * _HALAKIM_PER_HOUR) -_AM3_11_20 = ((9 * _HALAKIM_PER_HOUR) + 204) -_AM9_32_43 = ((15 * _HALAKIM_PER_HOUR) + 589) +import re #------------------------------------------------------------------------- # -# Conversion tables +# Constants # #------------------------------------------------------------------------- -monthsPerYear = [ - 12, 12, 13, 12, 12, 13, 12, 13, 12, - 12, 13, 12, 12, 13, 12, 12, 13, 12, 13 -] +UNDEF = -999999 +EXACT = 0 +ABOUT = 1 +BEFORE = 2 +AFTER = 3 + +#------------------------------------------------------------------------- +# +# Regular expressions for parsing +# +#------------------------------------------------------------------------- +_modifiers = '(' + \ + _("abt\.?") + '|' + \ + _("about") + '|' + \ + _("est\.?") + '|' + \ + _("circa") + '|' + \ + _("around") + '|' + \ + _("before") + '|' + \ + _("after") + '|' + \ + _("aft\.?") + '|' + \ + _("bef\.?") + \ + '|abt|aft|after|before|bef)' +_start = "^\s*" + _modifiers + "?\s*" +fmt1 = re.compile(_start+"(\S+)(\s+\d+\s*,)?\s*([?\d]+)?\s*$", re.IGNORECASE) +fmt2 = re.compile(_start+"(\d+)\.?\s+([^\d]+)(\s+\d+)?\s*$", re.IGNORECASE) +fmt3 = re.compile(_start+r"([?\d]+)\s*[./-]\s*([?\d]+)\s*[./-]\s*([?\d]+)\s*$", + re.IGNORECASE) +fmt7 = re.compile(_start+r"([?\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) -yearOffset = [ - 0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123, - 136, 148, 160, 173, 185, 197, 210, 222 -] #------------------------------------------------------------------------- # @@ -85,59 +77,227 @@ yearOffset = [ #------------------------------------------------------------------------- class Calendar: - months = [ + entryCode = 0 + + MONTHS = [ _("January"), _("February"), _("March"), _("April"), _("May"), _("June"), _("July"), _("August"), _("September"), _("October"), _("November"), _("December")] - + + M2NUM = { + (MONTHS[0][0:3]).lower(): 1, (MONTHS[1][0:3]).lower(): 2, + (MONTHS[2][0:3]).lower(): 3, (MONTHS[3][0:3]).lower(): 4, + (MONTHS[4][0:3]).lower(): 5, (MONTHS[5][0:3]).lower(): 6, + (MONTHS[6][0:3]).lower(): 7, (MONTHS[7][0:3]).lower(): 8, + (MONTHS[8][0:3]).lower(): 9, (MONTHS[9][0:3]).lower(): 10, + (MONTHS[10][0:3]).lower(): 11, (MONTHS[11][0:3]).lower(): 12 + } + + M2V = { + _("abt") : ABOUT, _("about") : ABOUT, + _("abt.") : ABOUT, _("est") : ABOUT, + _("est.") : ABOUT, _("circa") : ABOUT, + _("around") : ABOUT, _("before") : BEFORE, + _("bef") : BEFORE, _("bef.") : BEFORE, + _("after") : AFTER, _("aft.") : AFTER, + _("aft") : AFTER, + # And the untranslated versions for reading saved data from XML. + "abt" : ABOUT, "about" : ABOUT, + "bef" : BEFORE, "bef." : BEFORE, + "aft." : AFTER, "abt." : ABOUT, + "est." : ABOUT, "est" : ABOUT, + "after" : AFTER, "before" : BEFORE, + "aft" : AFTER, + } + + MODE = { + ABOUT : _("about"), + BEFORE : _("before"), + AFTER : _("after")} + + EM2NUM ={ + "jan" : 1, "feb" : 2, "mar" : 3, "apr" : 4, + "may" : 5, "jun" : 6, "jul" : 7, "aug" : 8, + "sep" : 9, "oct" :10, "nov" : 11,"dec" : 12 + } + + NAME = "Undefined Calendar" + TNAME = _("Undefined Calendar") + + def mlen(self): + return -1 + def __init__(self,source=None): if source: - self.set_sdn(source.get_sdn()) + self.get_ymd(source.get_sdn()) def month(self,val): try: - return Calendar.months[val-1] + return Calendar.MONTHS[val-1] except: return "Illegal Month" - def get_name(self): - return "ERROR" - def check(self): return 0 - def format(self,year,month,day,mode): - return self.display(year,month,day,year) + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (text,Calendar.NAME) + + def format_yymmdd(self,year,month,day,mode): + if month == UNDEF and day == UNDEF and year == UNDEF : + return "" + elif day == UNDEF: + if month == UNDEF: + retval = str(self.year) + elif self.year == UNDEF: + retval = "????-%02d-??" % (month) + else: + retval = "%04d-%02d" % (year,month) + elif month == UNDEF: + retval = "%04d-??-%02d" % (year,day) + else: + if year == UNDEF: + retval = "????-%02d-%02d" % (month,day) + else: + retval = "%04d-%02d-%02d" % (year,month,day) + + if Calendar.MODE.has_key(mode): + return "%s %s" % (Calendar.MODE[mode],retval) + else: + return retval def display(self,year,month,day,mode): - d = '' - if year==Date.UNDEF: - if month == Date.UNDEF: + if year==UNDEF: + if month == UNDEF: d = "" - elif day == Date.UNDEF: + elif day == UNDEF: d = self.month(month) else: d = "%02d %s" % (day,self.month(month)) - elif month == Date.UNDEF: + elif month == UNDEF: d = str(year) - elif day == Date.UNDEF: + elif day == UNDEF: d = "%s %d" % (self.month(month),year) else: d = "%02d %s %d" % (day,self.month(month),year) - if mode == Date.SingleDate.about: - d = _("about") + ' ' + d - elif mode == Date.SingleDate.before: - d = _("before") + ' ' + d - elif mode == Date.SingleDate.after: - d = _("after") + ' ' + d - return d - def set_sdn(self,val): + if Calendar.MODE.has_key(mode): + return "%s %s" % (Calendar.MODE[mode],d) + else: + return d + + def get_ymd(self,val): return (0,0,0) def get_sdn(self,y,m,d): return 0 + def set_mode_value(self,val): + if not val: + return EXACT + else: + try: + return Calendar.M2V[val.lower()] + except KeyError: + return EXACT + + def set_value(self,s): + try: + return int(s) + except: + return UNDEF + + def set_month_string(self,text): + val = unicode(text[0:self.mlen()]).lower() + try: + return Calendar.M2NUM[val] + except KeyError: + if Calendar.EM2NUM.has_key(val): + return Calendar.EM2NUM[val] + else: + return UNDEF + + def set(self,text): + mode = UNDEF + year = UNDEF + month = UNDEF + day = UNDEF + + match = fmt2.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + month = self.set_month_string(matches[2]) + day = self.set_value(matches[1]) + if len(matches) == 4 and matches[3] != None: + year = self.set_value(matches[3]) + return (year,month,day,mode) + + match = fmt5.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + year = self.set_value(matches[1]) + return (year,month,day,mode) + + match = fmt7.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + if Calendar.entryCode == 2: + month = self.set_value(matches[2]) + year = self.set_value(matches[1]) + else: + month = self.set_value(matches[1]) + year = self.set_value(matches[2]) + return (year,month,day,mode) + + match = fmt3.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + if Calendar.entryCode == 0: + month = self.set_value(matches[1]) + day = self.set_value(matches[2]) + year = self.set_value(matches[3]) + elif Calendar.entryCode == 1: + month = self.set_value(matches[2]) + day = self.set_value(matches[1]) + year = self.set_value(matches[3]) + else: + month = self.set_value(matches[2]) + day = self.set_value(matches[3]) + year = self.set_value(matches[1]) + return (year,month,day,mode) + + match = fmt1.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + month = self.set_month_string(unicode(matches[1])) + if matches[2]: + val = matches[2].replace(',','') + day = self.set_value(val) + year = self.set_value(matches[3]) + return (year,month,day,mode) + + match = fmt4.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + month = self.set_month_string(unicode(matches[1])) + if len(matches) == 4: + year = self.set_value(matches[3]) + return (year,month,day,mode) + + match = fmt6.match(text) + if match != None: + matches = match.groups() + mode = self.set_mode_value(matches[0]) + month = self.set_value(matches[1]) + + return (year,month,day,mode) + #------------------------------------------------------------------------- # # Hebrew calendar @@ -160,32 +320,51 @@ class Hebrew(Calendar): WEDNESDAY= 3 FRIDAY = 5 - NOON = (18 * _HALAKIM_PER_HOUR) - AM3_11_20 = ((9 * _HALAKIM_PER_HOUR) + 204) - AM9_32_43 = ((15 * _HALAKIM_PER_HOUR) + 589) + NOON = (18 * HALAKIM_PER_HOUR) + AM3_11_20 = ((9 * HALAKIM_PER_HOUR) + 204) + AM9_32_43 = ((15 * HALAKIM_PER_HOUR) + 589) monthsPerYear = [ - 12, 12, 13, 12, 12, 13, 12, 13, 12, - 12, 13, 12, 12, 13, 12, 12, 13, 12, 13 - ] + 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, + 13, 12, 12, 13, 12, 12, 13, 12, 13 ] yearOffset = [ 0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123, - 136, 148, 160, 173, 185, 197, 210, 222 - ] + 136, 148, 160, 173, 185, 197, 210, 222 ] - months = [ + MONTHS = [ "Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul",] + M2NUM = { + "tishri" : 1, "heshvan" : 2, "kislev" : 3, "tevet" : 4, + "shevat" : 5, "adari" : 6, "adarii" : 7, "nisan" : 8, + "iyyar" : 9, "sivan" :10, "tammuz" :11, "av" : 12, + "elul" : 13,"tsh" : 1, "csh" : 2, "ksl" : 3, + "tvt" : 4, "shv" : 5, "adr" : 6, "ads" : 7, + "nsn" : 8, "iyr" : 9, "svn" :10, "tmz" : 11, + "aav" :12, "ell" :13, + } + + NAME = "Hebrew" + TNAME = _("Hebrew") + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (self.display(year,month,day,mode),Hebrew.NAME) + def month(self,val): try: - return Hebrew.months[val-1] + return Hebrew.MONTHS[val-1] except: return "Illegal Month" + def set_month_string(self,text): + try: + return Hebrew.M2NUM[unicode(text.lower())] + except KeyError: + return UNDEF + def Tishri1(self,metonicYear, moladDay, moladHalakim): tishri1 = moladDay @@ -194,9 +373,10 @@ class Hebrew(Calendar): lastWasLeapYear = metonicYear in [ 3, 6, 8, 11, 14, 17, 0] # Apply rules 2, 3 and 4. - if ((moladHalakim >= NOON) or - ((not leapYear) and dow == TUESDAY and moladHalakim >= AM3_11_20) or - (lastWasLeapYear and dow == MONDAY and moladHalakim >= AM9_32_43)) : + if ((moladHalakim >= Hebrew.NOON) or + ((not leapYear) and dow == Hebrew.TUESDAY and + moladHalakim >= Hebrew.AM3_11_20) or + (lastWasLeapYear and dow == Hebrew.MONDAY and moladHalakim >= Hebrew.AM9_32_43)) : tishri1 = tishri1 + 1 dow = dow + 1 if dow == 7: @@ -205,7 +385,7 @@ class Hebrew(Calendar): # Apply rule 1 after the others because it can cause an additional # delay of one day - if dow == _WEDNESDAY or dow == FRIDAY or dow == SUNDAY: + if dow == Hebrew.WEDNESDAY or dow == Hebrew.FRIDAY or dow == Hebrew.SUNDAY: tishri1 = tishri1 + 1 return tishri1 @@ -214,32 +394,32 @@ class Hebrew(Calendar): # Start with the time of the first molad after creation. - r1 = NEW_MOON_OF_CREATION; + r1 = Hebrew.NEW_MOON_OF_CREATION # Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 # bits of the result will be in r2 and the lower 16 bits will be # in r1. - r1 = r1 + (metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF)) + r1 = r1 + (metonicCycle * (Hebrew.HALAKIM_PER_METONIC_CYCLE & 0xFFFF)) r2 = r1 >> 16 - r2 = r2 + (metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF)) + r2 = r2 + (metonicCycle * ((Hebrew.HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF)) # Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1, the # upper 16 bits of the quotient will be in d2 and the lower 16 bits # will be in d1. - d2 = r2 / HALAKIM_PER_DAY - r2 = r2 - (d2 * HALAKIM_PER_DAY) + d2 = r2 / Hebrew.HALAKIM_PER_DAY + r2 = r2 - (d2 * Hebrew.HALAKIM_PER_DAY) r1 = (r2 << 16) | (r1 & 0xFFFF) - d1 = r1 / HALAKIM_PER_DAY - r1 = r1 - ( d1 * HALAKIM_PER_DAY) + d1 = r1 / Hebrew.HALAKIM_PER_DAY + r1 = r1 - ( d1 * Hebrew.HALAKIM_PER_DAY) MoladDay = (d2 << 16) | d1 MoladHalakim = r1 return (MoladDay,MoladHalakim) - def FindTishriMolad(self,inputDay): + def TishriMolad(self,inputDay): # Estimate the metonic cycle number. Note that this may be an under # estimate because there are 6939.6896 days in a metonic cycle not @@ -250,7 +430,7 @@ class Hebrew(Calendar): # Calculate the time of the starting molad for this metonic cycle. */ - (moladDay, moladHalakim) = MoladOfMetonicCycle(metonicCycle) + (moladDay, moladHalakim) = self.MoladOfMetonicCycle(metonicCycle) # If the above was an under estimate, increment the cycle number until # the correct one is found. For modern dates this loop is about 98.6% @@ -259,9 +439,9 @@ class Hebrew(Calendar): while moladDay < (inputDay - 6940 + 310): metonicCycle = metonicCycle + 1 - moladHalakim = moladHalakim + HALAKIM_PER_METONIC_CYCLE - moladDay = moladDay + ( moladHalakim / HALAKIM_PER_DAY) - moladHalakim = moladHalakim % HALAKIM_PER_DAY + moladHalakim = moladHalakim + Hebrew.HALAKIM_PER_METONIC_CYCLE + moladDay = moladDay + ( moladHalakim / Hebrew.HALAKIM_PER_DAY) + moladHalakim = moladHalakim % Hebrew.HALAKIM_PER_DAY # Find the molad of Tishri closest to this date. @@ -270,136 +450,136 @@ class Hebrew(Calendar): break moladHalakim = moladHalakim + \ - (HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]) - moladDay = moladDay + (moladHalakim / HALAKIM_PER_DAY) - moladHalakim = moladHalakim % HALAKIM_PER_DAY + (Hebrew.HALAKIM_PER_LUNAR_CYCLE * Hebrew.monthsPerYear[metonicYear]) + moladDay = moladDay + (moladHalakim / Hebrew.HALAKIM_PER_DAY) + moladHalakim = moladHalakim % Hebrew.HALAKIM_PER_DAY else: metonicYear = metonicYear + 1 return (metonicCycle, metonicYear, moladDay, moladHalakim) - def FindStartOfYear(self,year): + def StartOfYear(self,year): - pMetonicCycle = (year - 1) / 19; - pMetonicYear = (year - 1) % 19; - (pMoladDay, pMoladHalakim) = MoladOfMetonicCycle(pMetonicCycle) + MetonicCycle = (year - 1) / 19; + MetonicYear = (year - 1) % 19; + (MoladDay, MoladHalakim) = self.MoladOfMetonicCycle(MetonicCycle) - pMoladHalakim = pMoladHalakim + (HALAKIM_PER_LUNAR_CYCLE * yearOffset[pMetonicYear]) - pMoladDay = pMoladDay + (pMoladHalakim / HALAKIM_PER_DAY) - pMoladHalakim = pMoladHalakim % HALAKIM_PER_DAY + MoladHalakim = MoladHalakim + (Hebrew.HALAKIM_PER_LUNAR_CYCLE * Hebrew.yearOffset[MetonicYear]) + MoladDay = MoladDay + (MoladHalakim / Hebrew.HALAKIM_PER_DAY) + MoladHalakim = MoladHalakim % Hebrew.HALAKIM_PER_DAY - pTishri1 = Tishri1(pMetonicYear, pMoladDay, pMoladHalakim); + pTishri1 = self.Tishri1(MetonicYear, MoladDay, MoladHalakim); - return (pMetonicCycle, pMetonicYear, pMoladDay, pMoladHalakim, pTishri1) + return (MetonicCycle, MetonicYear, MoladDay, MoladHalakim, pTishri1) - def set_sdn(self,sdn): + def get_ymd(self,sdn): """Converts an SDN number to a Julian calendar date""" - if sdn <= SDN_OFFSET : + if sdn <= Hebrew.SDN_OFFSET : return (0,0,0) - inputDay = sdn - SDN_OFFSET + inputDay = sdn - Hebrew.SDN_OFFSET - (metonicCycle, metonicYear, day, halakim) = FindTishriMolad(inputDay) - tishri1 = Tishri1(metonicYear, day, halakim); + (metonicCycle, metonicYear, day, halakim) = self.TishriMolad(inputDay) + tishri1 = self.Tishri1(metonicYear, day, halakim); if inputDay >= tishri1: # It found Tishri 1 at the start of the year - pYear = (metonicCycle * 19) + metonicYear + 1 + Year = (metonicCycle * 19) + metonicYear + 1 if inputDay < tishri1 + 59: if inputDay < tishri1 + 30: - pMonth = 1 - pDay = inputDay - tishri1 + 1 + Month = 1 + Day = inputDay - tishri1 + 1 else: - pMonth = 2 - pDay = inputDay - tishri1 - 29 - return (pYear, pMonth, pDay) + Month = 2 + Day = inputDay - tishri1 - 29 + return (Year, Month, Day) # We need the length of the year to figure this out, so find # Tishri 1 of the next year. */ - halakim = halakim + (HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]) - day = day + (halakim / HALAKIM_PER_DAY) - halakim = halakim % HALAKIM_PER_DAY; - tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim); + halakim = halakim + (Hebrew.HALAKIM_PER_LUNAR_CYCLE * Hebrew.monthsPerYear[metonicYear]) + day = day + (halakim / Hebrew.HALAKIM_PER_DAY) + halakim = halakim % Hebrew.HALAKIM_PER_DAY; + tishri1After = self.Tishri1((metonicYear + 1) % 19, day, halakim); else: # It found Tishri 1 at the end of the year. - pYear = metonicCycle * 19 + metonicYear + Year = metonicCycle * 19 + metonicYear if inputDay >= tishri1 - 177: # It is one of the last 6 months of the year. if inputDay > tishri1 - 30: - pMonth = 13 - pDay = inputDay - tishri1 + 30 + Month = 13 + Day = inputDay - tishri1 + 30 elif inputDay > tishri1 - 60: - pMonth = 12 - pDay = inputDay - tishri1 + 60 + Month = 12 + Day = inputDay - tishri1 + 60 elif inputDay > tishri1 - 89: - pMonth = 11 - pDay = inputDay - tishri1 + 89 + Month = 11 + Day = inputDay - tishri1 + 89 elif inputDay > tishri1 - 119: - pMonth = 10 - pDay = inputDay - tishri1 + 119 + Month = 10 + Day = inputDay - tishri1 + 119 elif inputDay > tishri1 - 148: - pMonth = 9 - pDay = inputDay - tishri1 + 148 + Month = 9 + Day = inputDay - tishri1 + 148 else: - pMonth = 8 - pDay = inputDay - tishri1 + 178 - return (pYear,pMonth,pDay) + Month = 8 + Day = inputDay - tishri1 + 178 + return (Year,Month,Day) else: - if monthsPerYear[(pYear - 1) % 19] == 13: - pMonth = 7 - pDay = inputDay - tishri1 + 207 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 + if Hebrew.monthsPerYear[(Year - 1) % 19] == 13: + Month = 7 + Day = inputDay - tishri1 + 207 + if Day > 0: + return (Year,Month,Day) + Month = Month - 1 + Day = Day + 30 + if Day > 0: + return (Year,Month,Day) + Month = Month - 1 + Day = Day + 30 else: - pMonth = 6 - pDay = inputDay - tishri1 + 207 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 + Month = 6 + Day = inputDay - tishri1 + 207 + if Day > 0: + return (Year,Month,Day) + Month = Month - 1 + Day = Day + 30 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 29 - if pDay > 0: - return (pYear,pMonth,pDay) + if Day > 0: + return (Year,Month,Day) + Month = Month - 1 + Day = Day + 29 + if Day > 0: + return (Year,Month,Day) # We need the length of the year to figure this out, so find - # Tishri 1 of this year. */ + # Tishri 1 of this year tishri1After = tishri1; - (metonicCycle,metonicYear,day,halakim) = FindTishriMolad(day-365) - tishri1 = Tishri1(metonicYear, day, halakim) + (metonicCycle,metonicYear,day,halakim) = self.TishriMolad(day-365) + tishri1 = self.Tishri1(metonicYear, day, halakim) yearLength = tishri1After - tishri1; - day = inputDay - tishri1 - 29; + cday = inputDay - tishri1 - 29; if yearLength == 355 or yearLength == 385 : # Heshvan has 30 days if day <= 30: - pMonth = 2 - pDay = day - return (pYear,pMonth,pDay) + Month = 2 + Day = cday + return (Year,Month,Day) day = day - 30 else: # Heshvan has 29 days if day <= 29: - pMonth = 2 - pDay = day - return (pYear,pMonth,pDay) + Month = 2 + Day = cday + return (Year,Month,Day) - day = day - 29 + cday = cday - 29 # It has to be Kislev - return (pYear,3,day) + return (Year,3,cday) def get_sdn(self,year, month, day): """Converts a Jewish calendar date to an SDN number""" @@ -408,7 +588,7 @@ class Hebrew(Calendar): if month == 1 or month == 2: # It is Tishri or Heshvan - don't need the year length. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = FindStartOfYear(year) + (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = self.StartOfYear(year) if month == 1: sdn = tishri1 + day - 1 else: @@ -417,13 +597,13 @@ class Hebrew(Calendar): # It is Kislev - must find the year length. # Find the start of the year. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = FindStartOfYear(year) + (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = self.StartOfYear(year) # Find the end of the year. - moladHalakim = moladHalakim + (HALAKIM_PER_LUNAR_CYCLE*monthsPerYear[metonicYear]) - moladDay = moladDay + (moladHalakim / HALAKIM_PER_DAY) - moladHalakim = moladHalakim % HALAKIM_PER_DAY - tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim) + moladHalakim = moladHalakim + (Hebrew.HALAKIM_PER_LUNAR_CYCLE*Hebrew.monthsPerYear[metonicYear]) + moladDay = moladDay + (moladHalakim / Hebrew.HALAKIM_PER_DAY) + moladHalakim = moladHalakim % Hebrew.HALAKIM_PER_DAY + tishri1After = self.Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim) yearLength = tishri1After - tishri1 @@ -434,9 +614,9 @@ class Hebrew(Calendar): elif month == 4 or month == 5 or month == 6: # It is Tevet, Shevat or Adar I - don't need the year length - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = FindStartOfYear(year+1) + (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = self.StartOfYear(year+1) - if monthsPerYear[(year - 1) % 19] == 12: + if Hebrew.monthsPerYear[(year - 1) % 19] == 12: lengthOfAdarIAndII = 29 else: lengthOfAdarIAndII = 59 @@ -449,7 +629,7 @@ class Hebrew(Calendar): sdn = tishri1After + day - lengthOfAdarIAndII - 178 else: # It is Adar II or later - don't need the year length. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = FindStartOfYear(year+1) + (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = self.StartOfYear(year+1) if month == 7: sdn = tishri1After + day - 207 @@ -467,7 +647,7 @@ class Hebrew(Calendar): sdn = tishri1After + day - 30 else: return 0 - return sdn + SDN_OFFSET + return sdn + Hebrew.SDN_OFFSET #------------------------------------------------------------------------- # @@ -477,7 +657,36 @@ class Hebrew(Calendar): class Persian(Calendar): """Persian Calendar""" - PERSIAN_EPOCH = 1948320.5; + EPOCH = 1948320.5 + SDN_475_1_1 = 2121446 + + MONTHS = [ "Farvardin", "Ordibehesht", "Khordad", "Tir", "Mordad", + "Shahrivar", "Mehr", "Aban", "Azar", "Dey", "Bahman", "Esfand" ] + + M2NUM = { + "farvardin" : 1, "ordibehesht" : 2, "khordad" : 3, + "tir" : 4, "mordad" : 5, "shahrivar" : 6, + "mehr" : 7, "aban" : 8, "azar" : 9, + "dey" : 10, "bahman" : 11, "esfand" : 12 + } + + NAME = "Persian" + TNAME = _("Persian") + + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (self.display(year,month,day,mode),Persian.NAME) + + def set_month_string(self,text): + try: + return Persian.M2NUM[unicode(text.lower())] + except KeyError: + return UNDEF + + def month(self,val): + try: + return Persian.MONTHS[val-1] + except: + return "Illegal Month" def get_sdn(self,year, month, day): if year >= 0: @@ -495,12 +704,12 @@ class Persian(Calendar): v3 = (epyear - 1) * 365 + day v4 = math.floor(epbase / 2820) * 1029983 - return int(math.ceil(v1 + v2 + v3 + v4 + PERSIAN_EPOCH - 1)) + return int(math.ceil(v1 + v2 + v3 + v4 + Persian.EPOCH - 1)) - def set_sdn(self,sdn): + def get_ymd(self,sdn): sdn = math.floor(sdn) + 0.5 - depoch = sdn - persian_to_sdn(475, 1, 1) + depoch = sdn - self.get_sdn(475,1,1) cycle = math.floor(depoch / 1029983) cyear = depoch % 1029983 if cyear == 1029982: @@ -514,12 +723,12 @@ class Persian(Calendar): if year <= 0: year = year - 1; - yday = sdn - persian_to_sdn(year, 1, 1) + 1 + yday = sdn - self.get_sdn(year, 1, 1) + 1 if yday < 186: month = math.ceil(yday / 31) else: month = math.ceil((yday - 6) / 30) - day = (sdn - persian_to_sdn(year, month, 1)) + 1 + day = (sdn - self.get_sdn(year, month, 1)) + 1 return (int(year), int(month), int(day)) #------------------------------------------------------------------------- @@ -536,21 +745,60 @@ class FrenchRepublic(Calendar): FIRST_VALID = 2375840 LAST_VALID = 2380952 + MONTHS = [ + unicode("Vendémiaire",'latin-1'), unicode("Brumaire",'latin-1'), + unicode("Frimaire",'latin-1'), unicode("Nivôse",'latin-1'), + unicode("Pluviôse",'latin-1'), unicode("Ventôse",'latin-1'), + unicode("Germinal",'latin-1'), unicode("Floréal",'latin-1'), + unicode("Prairial",'latin-1'), unicode("Messidor",'latin-1'), + unicode("Thermidor",'latin-1'), unicode("Fructidor",'latin-1'), + unicode("Extra",'latin-1'),] + + M2NUM = { + "vend" : 1, "brum" : 2, "frim" : 3, "nivo" : 4, "pluv" : 5, "vent" : 6, + "germ" : 7, "flor" : 8, "prai" : 9, "mess" :10, "ther" :11, "fruc" :12, + "extr" : 13,"comp" :13, unicode("nivô",'latin-1') : 4 + } + + NAME = "French Republican" + TNAME = _("French Republican") + + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (self.display(year,month,day,mode),FrenchRepublic.NAME) + + def mlen(self): + return 4 + + def month(self,val): + try: + return FrenchRepublic.MONTHS[val-1] + except: + return "Illegal Month" + + def set_month_string(self,text): + val = (unicode(text)[0:4]).lower() + try: + return FrenchRepublic.M2NUM[val] + except KeyError: + return UNDEF + def get_sdn(self,y,m,d): """Converts a French Republican Calendar date to an SDN number""" if (y < 1 or y > 14 or m < 1 or m > 13 or d < 1 or d > 30): return 0 - return (y*DAYS_PER_4_YEARS)/4+(m-1)*DAYS_PER_MONTH+d+SDN_OFFSET + return (y*FrenchRepublic.DAYS_PER_4_YEARS)/4 + \ + (m-1)*FrenchRepublic.DAYS_PER_MONTH + \ + d + FrenchRepublic.SDN_OFFSET - def set_sdn(self,sdn): + def get_ymd(self,sdn): """Converts an SDN number to a French Republican Calendar date""" - if (sdn < FIRST_VALID or sdn > LAST_VALID) : + if (sdn < FrenchRepublic.FIRST_VALID or sdn > FrenchRepublic.LAST_VALID) : return (0,0,0) - temp = (sdn-SDN_OFFSET)*4 - 1 - year = temp/DAYS_PER_4_YEARS - dayOfYear = (temp%DAYS_PER_4_YEARS)/4 - month = (dayOfYear/DAYS_PER_MONTH)+1 - day = (dayOfYear%DAYS_PER_MONTH)+1 + temp = (sdn-FrenchRepublic.SDN_OFFSET)*4 - 1 + year = temp/FrenchRepublic.DAYS_PER_4_YEARS + dayOfYear = (temp%FrenchRepublic.DAYS_PER_4_YEARS)/4 + month = (dayOfYear/FrenchRepublic.DAYS_PER_MONTH)+1 + day = (dayOfYear%FrenchRepublic.DAYS_PER_MONTH)+1 return (year,month,day) #------------------------------------------------------------------------- @@ -566,26 +814,35 @@ class Gregorian(Calendar): DAYS_PER_4_YEARS = 1461 DAYS_PER_400_YEARS = 146097 - def get_sdn(self,sdn): + NAME = "Gregorian" + TNAME = _("Gregorian") + + def quote_display(self,year,month,day,mode): + return self.display(year,month,day,mode) + + def mlen(self): + return 3 + + def get_ymd(self,sdn): """Converts an SDN number to a gregorial date""" if sdn <= 0: return (0,0,0) - temp = (sdn + SDN_OFFSET) * 4 - 1 + temp = (Gregorian.SDN_OFFSET + sdn) * 4 - 1 # Calculate the century (year/100) - century = temp / DAYS_PER_400_YEARS + century = temp / Gregorian.DAYS_PER_400_YEARS # Calculate the year and day of year (1 <= dayOfYear <= 366) - temp = ((temp % DAYS_PER_400_YEARS) / 4) * 4 + 3 - year = (century * 100) + (temp / DAYS_PER_4_YEARS) - dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1 + temp = ((temp % Gregorian.DAYS_PER_400_YEARS) / 4) * 4 + 3 + year = (century * 100) + (temp / Gregorian.DAYS_PER_4_YEARS) + dayOfYear = (temp % Gregorian.DAYS_PER_4_YEARS) / 4 + 1 # Calculate the month and day of month temp = dayOfYear * 5 - 3 - month = temp / DAYS_PER_5_MONTHS - day = (temp % DAYS_PER_5_MONTHS) / 5 + 1 + month = temp / Gregorian.DAYS_PER_5_MONTHS + day = (temp % Gregorian.DAYS_PER_5_MONTHS) / 5 + 1 # Convert to the normal beginning of the year if month < 10 : @@ -602,7 +859,7 @@ class Gregorian(Calendar): return (year,month,day) - def set_sdn(self,iyear,imonth,iday): + def get_sdn(self,iyear,imonth,iday): """Converts a gregorian date to an SDN number""" # check for invalid dates if iyear==0 or iyear<-4714 or imonth<=0 or imonth>12 or iday<=0 or iday>31: @@ -626,11 +883,11 @@ class Gregorian(Calendar): month = imonth + 9 year = year - 1 - return( ((year / 100) * DAYS_PER_400_YEARS) / 4 - + ((year % 100) * DAYS_PER_4_YEARS) / 4 - + (month * DAYS_PER_5_MONTHS + 2) / 5 + return( ((year / 100) * Gregorian.DAYS_PER_400_YEARS) / 4 + + ((year % 100) * Gregorian.DAYS_PER_4_YEARS) / 4 + + (month * Gregorian.DAYS_PER_5_MONTHS + 2) / 5 + iday - - SDN_OFFSET ); + - Gregorian.SDN_OFFSET ); #------------------------------------------------------------------------- # @@ -644,21 +901,30 @@ class Julian(Calendar): DAYS_PER_5_MONTHS = 153 DAYS_PER_4_YEARS = 1461 - def get_sdn(self,sdn): + NAME = "Julian" + TNAME = _("Julian") + + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (self.display(year,month,day,mode),Julian.NAME) + + def mlen(self): + return 3 + + def get_ymd(self,sdn): """Converts an SDN number to a Julian date""" if sdn <= 0 : return (0,0,0) - temp = (sdn + SDN_OFFSET) * 4 - 1 + temp = (sdn + Julian.SDN_OFFSET) * 4 - 1 # Calculate the year and day of year (1 <= dayOfYear <= 366) - year = temp / DAYS_PER_4_YEARS - dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1 + year = temp / Julian.DAYS_PER_4_YEARS + dayOfYear = (temp % Julian.DAYS_PER_4_YEARS) / 4 + 1 # Calculate the month and day of month temp = dayOfYear * 5 - 3; - month = temp / DAYS_PER_5_MONTHS; - day = (temp % DAYS_PER_5_MONTHS) / 5 + 1; + month = temp / Julian.DAYS_PER_5_MONTHS; + day = (temp % Julian.DAYS_PER_5_MONTHS) / 5 + 1; # Convert to the normal beginning of the year if month < 10: @@ -674,7 +940,7 @@ class Julian(Calendar): return (year,month,day) - def set_sdn(self,iyear,imonth,iday): + def get_sdn(self,iyear,imonth,iday): """Converts a Julian calendar date to an SDN number""" # check for invalid dates @@ -699,7 +965,9 @@ class Julian(Calendar): month = imonth + 9 year = year - 1 - return (year*DAYS_PER_4_YEARS)/4 + (month*DAYS_PER_5_MONTHS+2)/5 + iday - SDN_OFFSET + return (year*Julian.DAYS_PER_4_YEARS)/4 + \ + (month*Julian.DAYS_PER_5_MONTHS+2)/5 + \ + iday - Julian.SDN_OFFSET #------------------------------------------------------------------------- # @@ -709,462 +977,103 @@ class Julian(Calendar): class Islamic(Calendar): """Islamic calendar""" - ISLAMIC_EPOCH = 1948439.5 + EPOCH = 1948439.5 - def set_sdn(self,year, month, day): + MONTHS = [ + "Muharram", "Safar", "Rabi`al-Awwal", "Rabi`ath-Thani", + "Jumada l-Ula", "Jumada t-Tania", "Rajab", "Sha`ban", + "Ramadan", "Shawwal", "Dhu l-Qa`da", "Dhu l-Hijja" + ] + + M2NUM = { + "muharram" : 1, "safar" : 2, "rabi`al-awwal" : 3, + "rabi`ath-thani" : 4, "jumada l-ula" : 5 , "jumada t-tania" : 6, + "rajab" : 7, "sha`ban" : 8, "ramadan" : 9, + "shawwal" : 10, "dhu l-qa`da" : 11, "dhu l-hijja" : 12 + } + + NAME = "Islamic" + TNAME = _("Islamic") + + def quote_display(self,year,month,day,mode): + return "%s (%s)" % (self.display(year,month,day,mode),Islamic.NAME) + + def set_month_string(self,text): + try: + return Islamic.M2NUM[unicode(text.lower())] + except KeyError: + return UNDEF + + def month(self,val): + try: + return Islamic.MONTHS[val-1] + except: + return "Illegal Month" + + def get_sdn(self,year, month, day): v1 = math.ceil(29.5 * (month - 1)) v2 = (year - 1) * 354 v3 = math.floor((3 + (11 *year)) / 30) - return int(math.ceil((day + v1 + v2 + v3 + _ISLAMIC_EPOCH) - 1)) + return int(math.ceil((day + v1 + v2 + v3 + Islamic.EPOCH) - 1)) - def get_sdn(self,sdn): + def get_ymd(self,sdn): sdn = math.floor(sdn) + 0.5 - year = int(math.floor(((30*(sdn-_ISLAMIC_EPOCH))+10646)/10631)) - month = int(min(12, math.ceil((sdn-(29+islamic_to_sdn(year,1,1)))/29.5) + 1)) - day = int((sdn - islamic_to_sdn(year,month,1)) + 1) + year = int(math.floor(((30*(sdn-Islamic.EPOCH))+10646)/10631)) + month = int(min(12, math.ceil((sdn-(29+self.get_sdn(year,1,1)))/29.5) + 1)) + day = int((sdn - self.get_sdn(year,month,1)) + 1) return (year,month,day) - + #------------------------------------------------------------------------- # -# Tasks +# Calendar registration # #------------------------------------------------------------------------- -def sdn_to_julian(sdn): - """Converts an SDN number to a Julian date""" - if sdn <= 0 : - return (0,0,0) - - temp = (sdn + _J_SDN_OFFSET) * 4 - 1 - - # Calculate the year and day of year (1 <= dayOfYear <= 366) - year = temp / _J_DAYS_PER_4_YEARS - dayOfYear = (temp % _J_DAYS_PER_4_YEARS) / 4 + 1 - - # Calculate the month and day of month - temp = dayOfYear * 5 - 3; - month = temp / _J_DAYS_PER_5_MONTHS; - day = (temp % _J_DAYS_PER_5_MONTHS) / 5 + 1; - - # Convert to the normal beginning of the year - if month < 10: - month = month + 3 - else: - year = year + 1 - month = month - 9 - - # Adjust to the B.C./A.D. type numbering - year = year - 4800 - if year <= 0: - year = year - 1 - - return (year,month,day) - -def julian_to_sdn(iyear,imonth,iday): - """Converts a Julian calendar date to an SDN number""" - - # check for invalid dates - if iyear==0 or iyear<-4713 or imonth<=0 or imonth>12 or iday<=0 or iday>31: - return 0 - - # check for dates before SDN 1 (Jan 2, 4713 B.C.) - if iyear == -4713: - if imonth == 1 and iday == 1: - return 0 - - # Make year always a positive number - if iyear < 0: - year = iyear + 4801 - else: - year = iyear + 4800 - - # Adjust the start of the year - if imonth > 2: - month = imonth - 3 - else: - month = imonth + 9 - year = year - 1 - - return (year*_J_DAYS_PER_4_YEARS)/4 + (month*_J_DAYS_PER_5_MONTHS+2)/5 + iday - _J_SDN_OFFSET - -def french_to_sdn(y,m,d): - """Converts a French Republican Calendar date to an SDN number""" - if (y < 1 or y > 14 or m < 1 or m > 13 or d < 1 or d > 30): - return 0 - return (y*_FR_DAYS_PER_4_YEARS)/4+(m-1)*_FR_DAYS_PER_MONTH+d+_FR_SDN_OFFSET - -def sdn_to_french(sdn): - """Converts an SDN number to a French Republican Calendar date""" - if (sdn < _FR_FIRST_VALID or sdn > _FR_LAST_VALID) : - return (0,0,0) - temp = (sdn-_FR_SDN_OFFSET)*4 - 1 - year = temp/_FR_DAYS_PER_4_YEARS - dayOfYear = (temp%_FR_DAYS_PER_4_YEARS)/4 - month = (dayOfYear/_FR_DAYS_PER_MONTH)+1 - day = (dayOfYear%_FR_DAYS_PER_MONTH)+1 - return (year,month,day) - - -def sdn_to_gregorian(sdn): - """Converts an SDN number to a gregorial date""" - if sdn <= 0: - return (0,0,0) - - temp = (sdn + _GR_SDN_OFFSET) * 4 - 1 - - # Calculate the century (year/100) - century = temp / _GR_DAYS_PER_400_YEARS - - # Calculate the year and day of year (1 <= dayOfYear <= 366) - - temp = ((temp % _GR_DAYS_PER_400_YEARS) / 4) * 4 + 3 - year = (century * 100) + (temp / _GR_DAYS_PER_4_YEARS) - dayOfYear = (temp % _GR_DAYS_PER_4_YEARS) / 4 + 1 - - # Calculate the month and day of month - temp = dayOfYear * 5 - 3 - month = temp / _GR_DAYS_PER_5_MONTHS - day = (temp % _GR_DAYS_PER_5_MONTHS) / 5 + 1 - - # Convert to the normal beginning of the year - if month < 10 : - month = month + 3 - else: - year = year + 1 - month = month - 9 - - # Adjust to the B.C./A.D. type numbering - year = year - 4800 - if year <= 0: - year = year - 1 - - return (year,month,day) - -def gregorian_to_sdn(iyear,imonth,iday): - """Converts a gregorian date to an SDN number""" - # check for invalid dates - if iyear==0 or iyear<-4714 or imonth<=0 or imonth>12 or iday<=0 or iday>31: - return 0 - - # check for dates before SDN 1 (Nov 25, 4714 B.C.) - if iyear == -4714: - if imonth < 11 or imonth == 11 and iday < 25: - return 0 - - if iyear < 0: - year = iyear + 4801 - else: - year = iyear + 4800 - - # Adjust the start of the year - - if imonth > 2: - month = imonth - 3 - else: - month = imonth + 9 - year = year - 1 - - return( ((year / 100) * _GR_DAYS_PER_400_YEARS) / 4 - + ((year % 100) * _GR_DAYS_PER_4_YEARS) / 4 - + (month * _GR_DAYS_PER_5_MONTHS + 2) / 5 - + iday - - _GR_SDN_OFFSET ); - -def Tishri1(metonicYear, moladDay, moladHalakim): - - tishri1 = moladDay - dow = tishri1 % 7 - leapYear = metonicYear == 2 or metonicYear == 5 or metonicYear == 7 or \ - metonicYear == 10 or metonicYear == 13 or metonicYear == 16 or \ - metonicYear == 18 - lastWasLeapYear = metonicYear == 3 or metonicYear == 6 or metonicYear == 8 or \ - metonicYear == 11 or metonicYear == 14 or metonicYear == 17 or \ - metonicYear == 0 - - # Apply rules 2, 3 and 4. - if ((moladHalakim >= _NOON) or - ((not leapYear) and dow == _TUESDAY and moladHalakim >= _AM3_11_20) or - (lastWasLeapYear and dow == _MONDAY and moladHalakim >= _AM9_32_43)) : - tishri1 = tishri1 + 1 - dow = dow + 1 - if dow == 7: - dow = 0 - - # Apply rule 1 after the others because it can cause an additional - # delay of one day - - if dow == _WEDNESDAY or dow == _FRIDAY or dow == _SUNDAY: - tishri1 = tishri1 + 1 - - return tishri1 - - -def MoladOfMetonicCycle(metonicCycle): - - # Start with the time of the first molad after creation. - - r1 = _NEW_MOON_OF_CREATION; - - # Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 - # bits of the result will be in r2 and the lower 16 bits will be - # in r1. - - r1 = r1 + (metonicCycle * (_HALAKIM_PER_METONIC_CYCLE & 0xFFFF)) - r2 = r1 >> 16 - r2 = r2 + (metonicCycle * ((_HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF)) - - # Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1, the - # upper 16 bits of the quotient will be in d2 and the lower 16 bits - # will be in d1. - - d2 = r2 / _HALAKIM_PER_DAY - r2 = r2 - (d2 * _HALAKIM_PER_DAY) - r1 = (r2 << 16) | (r1 & 0xFFFF) - d1 = r1 / _HALAKIM_PER_DAY - r1 = r1 - ( d1 * _HALAKIM_PER_DAY) - - MoladDay = (d2 << 16) | d1 - MoladHalakim = r1 - - return (MoladDay,MoladHalakim) - -def FindTishriMolad(inputDay): - - # Estimate the metonic cycle number. Note that this may be an under - # estimate because there are 6939.6896 days in a metonic cycle not - # 6940, but it will never be an over estimate. The loop below will - # correct for any error in this estimate. */ - - metonicCycle = (inputDay + 310) / 6940 - - # Calculate the time of the starting molad for this metonic cycle. */ - - (moladDay, moladHalakim) = MoladOfMetonicCycle(metonicCycle) - - # If the above was an under estimate, increment the cycle number until - # the correct one is found. For modern dates this loop is about 98.6% - # likely to not execute, even once, because the above estimate is - # really quite close. - - while moladDay < (inputDay - 6940 + 310): - metonicCycle = metonicCycle + 1 - moladHalakim = moladHalakim + _HALAKIM_PER_METONIC_CYCLE - moladDay = moladDay + ( moladHalakim / _HALAKIM_PER_DAY) - moladHalakim = moladHalakim % _HALAKIM_PER_DAY - - # Find the molad of Tishri closest to this date. - - for metonicYear in range(0,18): - if moladDay > inputDay - 74: - break - - moladHalakim = moladHalakim + \ - (_HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]) - moladDay = moladDay + (moladHalakim / _HALAKIM_PER_DAY) - moladHalakim = moladHalakim % _HALAKIM_PER_DAY - else: - metonicYear = metonicYear + 1 - return (metonicCycle, metonicYear, moladDay, moladHalakim) - -def FindStartOfYear(year): - - pMetonicCycle = (year - 1) / 19; - pMetonicYear = (year - 1) % 19; - (pMoladDay, pMoladHalakim) = MoladOfMetonicCycle(pMetonicCycle) - - pMoladHalakim = pMoladHalakim + (_HALAKIM_PER_LUNAR_CYCLE * yearOffset[pMetonicYear]) - pMoladDay = pMoladDay + (pMoladHalakim / _HALAKIM_PER_DAY) - pMoladHalakim = pMoladHalakim % _HALAKIM_PER_DAY - - pTishri1 = Tishri1(pMetonicYear, pMoladDay, pMoladHalakim); - - return (pMetonicCycle, pMetonicYear, pMoladDay, pMoladHalakim, pTishri1) - -def sdn_to_jewish(sdn): - """Converts an SDN number to a Julian calendar date""" - - if sdn <= _H_SDN_OFFSET : - return (0,0,0) - - inputDay = sdn - _H_SDN_OFFSET - - (metonicCycle, metonicYear, day, halakim) = FindTishriMolad(inputDay) - tishri1 = Tishri1(metonicYear, day, halakim); - - if inputDay >= tishri1: - # It found Tishri 1 at the start of the year - - pYear = (metonicCycle * 19) + metonicYear + 1 - if inputDay < tishri1 + 59: - if inputDay < tishri1 + 30: - pMonth = 1 - pDay = inputDay - tishri1 + 1 - else: - pMonth = 2 - pDay = inputDay - tishri1 - 29 - return (pYear, pMonth, pDay) - - # We need the length of the year to figure this out, so find - # Tishri 1 of the next year. */ - - halakim = halakim + (_HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]) - day = day + (halakim / _HALAKIM_PER_DAY) - halakim = halakim % _HALAKIM_PER_DAY; - tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim); - else: - # It found Tishri 1 at the end of the year. - - pYear = metonicCycle * 19 + metonicYear - if inputDay >= tishri1 - 177: - # It is one of the last 6 months of the year. - if inputDay > tishri1 - 30: - pMonth = 13 - pDay = inputDay - tishri1 + 30 - elif inputDay > tishri1 - 60: - pMonth = 12 - pDay = inputDay - tishri1 + 60 - elif inputDay > tishri1 - 89: - pMonth = 11 - pDay = inputDay - tishri1 + 89 - elif inputDay > tishri1 - 119: - pMonth = 10 - pDay = inputDay - tishri1 + 119 - elif inputDay > tishri1 - 148: - pMonth = 9 - pDay = inputDay - tishri1 + 148 - else: - pMonth = 8 - pDay = inputDay - tishri1 + 178 - return (pYear,pMonth,pDay) - else: - if monthsPerYear[(pYear - 1) % 19] == 13: - pMonth = 7 - pDay = inputDay - tishri1 + 207 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 - else: - pMonth = 6 - pDay = inputDay - tishri1 + 207 - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 30 - - if pDay > 0: - return (pYear,pMonth,pDay) - pMonth = pMonth - 1 - pDay = pDay + 29 - if pDay > 0: - return (pYear,pMonth,pDay) - - # We need the length of the year to figure this out, so find - # Tishri 1 of this year. */ - tishri1After = tishri1; - (metonicCycle,metonicYear,day,halakim) = FindTishriMolad(day-365) - tishri1 = Tishri1(metonicYear, day, halakim) - - yearLength = tishri1After - tishri1; - day = inputDay - tishri1 - 29; - if yearLength == 355 or yearLength == 385 : - # Heshvan has 30 days - if day <= 30: - pMonth = 2 - pDay = day - return (pYear,pMonth,pDay) - day = day - 30 - else: - # Heshvan has 29 days - if day <= 29: - pMonth = 2 - pDay = day - return (pYear,pMonth,pDay) - - day = day - 29 - - # It has to be Kislev - return (pYear,3,day) - - -def jewish_to_sdn(year, month, day): - """Converts a Jewish calendar date to an SDN number""" - if year <= 0 or day <= 0 or day > 30 : - return 0 - - if month == 1 or month == 2: - # It is Tishri or Heshvan - don't need the year length. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = FindStartOfYear(year) - if month == 1: - sdn = tishri1 + day - 1 - else: - sdn = tishri1 + day + 29 - elif month == 3: - # It is Kislev - must find the year length. - - # Find the start of the year. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1) = FindStartOfYear(year) - - # Find the end of the year. - moladHalakim = moladHalakim + (_HALAKIM_PER_LUNAR_CYCLE*monthsPerYear[metonicYear]) - moladDay = moladDay + (moladHalakim / _HALAKIM_PER_DAY) - moladHalakim = moladHalakim % _HALAKIM_PER_DAY - tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim) - - yearLength = tishri1After - tishri1 - - if yearLength == 355 or yearLength == 385: - sdn = tishri1 + day + 59 - else: - sdn = tishri1 + day + 58 - elif month == 4 or month == 5 or month == 6: - # It is Tevet, Shevat or Adar I - don't need the year length - - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = FindStartOfYear(year+1) - - if monthsPerYear[(year - 1) % 19] == 12: - lengthOfAdarIAndII = 29 - else: - lengthOfAdarIAndII = 59 - - if month == 4: - sdn = tishri1After + day - lengthOfAdarIAndII - 237 - elif month == 5: - sdn = tishri1After + day - lengthOfAdarIAndII - 208 - else: - sdn = tishri1After + day - lengthOfAdarIAndII - 178 - else: - # It is Adar II or later - don't need the year length. - (metonicCycle,metonicYear,moladDay,moladHalakim,tishri1After) = FindStartOfYear(year+1) - - if month == 7: - sdn = tishri1After + day - 207 - elif month == 8: - sdn = tishri1After + day - 178 - elif month == 9: - sdn = tishri1After + day - 148 - elif month == 10: - sdn = tishri1After + day - 119 - elif month == 11: - sdn = tishri1After + day - 89 - elif month == 12: - sdn = tishri1After + day - 60 - elif month == 13: - sdn = tishri1After + day - 30 - else: - return 0 - return sdn + _H_SDN_OFFSET +_calendars = {} + +def register( class_obj ): + _calendars[class_obj.NAME] = class_obj + +def find_calendar(name): + try: + return _calendars[name] + except: + return None + +def calendar_names(): + list = [] + for n in _calendars.values(): + list.append(n) + list.sort() + return list + +register(Gregorian) +register(FrenchRepublic) +register(Julian) +register(Persian) +register(Hebrew) +register(Islamic) if __name__ == "__main__": e = Gregorian() - print e.format(1992,12,2,Date.SingleDate.exact) - print e.format(2002,1,28,Date.SingleDate.about) + print e.get_ymd(e.get_sdn(1992,12,2)), e.display(1992,12,2,EXACT) + + a = Julian() + print a.get_ymd(a.get_sdn(2002,1,28)), a.display(2002,1,28,ABOUT) f = Hebrew() - print f.format(1992,12,2,Date.SingleDate.exact) + print f.get_ymd(f.get_sdn(1992,12,2)), f.display(1992,12,2,EXACT) + + e = Gregorian() + print e.get_ymd(e.get_sdn(1992,12,2)), e.display(1992,12,2,EXACT) + + g = Islamic() + print g.get_ymd(g.get_sdn(1992,12,2)), g.display(1992,12,2,EXACT) + + h = Persian() + print h.get_ymd(h.get_sdn(1992,12,2)), h.display(1992,12,2,EXACT) + + i = FrenchRepublic() + print i.get_ymd(i.get_sdn(1992,12,2)), i.display(1992,12,2,EXACT) diff --git a/src/Date.py b/src/Date.py index 93dc90a8d..ec35a1101 100644 --- a/src/Date.py +++ b/src/Date.py @@ -42,68 +42,18 @@ from intl import gettext as _ #------------------------------------------------------------------------- # -# Calendar Mappings +# Constants # #------------------------------------------------------------------------- -GREGORIAN = 0 -JULIAN = 1 -HEBREW = 2 -FRENCH = 3 - -#------------------------------------------------------------------------- -# -# Month mappings -# -#------------------------------------------------------------------------- -_fmonth = [ - unicode("Vendémiaire",'latin-1'), unicode("Brumaire",'latin-1'), - unicode("Frimaire",'latin-1'), unicode("Nivôse",'latin-1'), - unicode("Pluviôse",'latin-1'), unicode("Ventôse",'latin-1'), - unicode("Germinal",'latin-1'), unicode("Floréal",'latin-1'), - unicode("Prairial",'latin-1'), unicode("Messidor",'latin-1'), - unicode("Thermidor",'latin-1'), unicode("Fructidor",'latin-1'), - unicode("Extra",'latin-1'), - ] - -_fmonth2num = { - "vend" : 0, "brum" : 1, "frim" : 2, "nivo" : 3, "pluv" : 4, "vent" : 5, - "germ" : 6, "flor" : 7, "prai" : 8, "mess" : 9, "ther" :10, "fruc" :11, - "extr" : 12,"comp" :12, unicode("nivô",'latin-1') : 3 - } - -_hmonth = [ - "Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", - "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", - "Elul", - ] - -_hmonth2num = { - "tishri" : 0, "heshvan" : 1, "kislev" : 2, "tevet" : 3, - "shevat" : 4, "adari" : 5, "adarii" : 6, "nisan" : 7, - "iyyar" : 8, "sivan" : 9, "tammuz" :10, "av" : 11, - "elul" : 12,"tsh" : 0, "csh" : 1, "ksl" : 2, - "tvt" : 3, "shv" : 4, "adr" : 5, "ads" : 6, - "nsn" : 7, "iyr" : 8, "svn" : 9, "tmz" : 10, - "aav" :11, "ell" :12, - } - -_mname = [ - _("January"), _("February"), _("March"), _("April"), - _("May"), _("June"), _("July"), _("August"), - _("September"), _("October"), _("November"), _("December") - ] - -_m2num = { - string.lower(_mname[0][0:3]): 0, string.lower(_mname[1][0:3]): 1, - string.lower(_mname[2][0:3]): 2, string.lower(_mname[3][0:3]): 3, - string.lower(_mname[4][0:3]): 4, string.lower(_mname[5][0:3]): 5, - string.lower(_mname[6][0:3]): 6, string.lower(_mname[7][0:3]): 7, - string.lower(_mname[8][0:3]): 8, string.lower(_mname[9][0:3]): 9, - string.lower(_mname[10][0:3]): 10, string.lower(_mname[11][0:3]): 11 - } - UNDEF = -999999 +_calendar_val = [ + Calendar.Gregorian, + Calendar.Julian, + Calendar.Hebrew, + Calendar.FrenchRepublic, + ] + #------------------------------------------------------------------------- # # Date class @@ -115,7 +65,6 @@ class Date: date ranges, and alternate calendars. """ formatCode = 0 - entryCode = 0 Error = "Illegal Date" @@ -139,13 +88,26 @@ class Date: self.stop = None self.range = 0 self.text = "" - self.calendar = GREGORIAN + self.calendar = Calendar.Gregorian() def get_calendar(self): return self.calendar def set_calendar(self,val): + self.calendar = val() + self.start.convert_to(val) + if self.stop: + self.stop.convert_to(val) + + def set_calendar_obj(self,val): self.calendar = val + self.start.convert_to_obj(val) + if self.stop: + self.stop.convert_to_obj(val) + + def set_calendar_val(self,integer): + val = _calendar_val[integer] + self.calendar = val() self.start.convert_to(val) if self.stop: self.stop.convert_to(val) @@ -251,62 +213,29 @@ class Date: def set_range(self,val): self.range = val - - def get_fmt(self,func): - if self.range == 0: - return func(self.start) - elif self.range == -1: - return self.text - else: - d1 = func(self.start) - d2 = func(self.stop) - return _("from %(start_date)s to %(stop_date)s") % { - 'start_date' : d1, - 'stop_date' : d2 } def getDate(self): - return self.get_fmt(SingleDate.getDate) + if self.range == 0: + return self.start.getDate() + elif self.range == -1: + return "%s" % self.text + else: + return _("from %(start_date)s to %(stop_date)s") % { + 'start_date' : self.start.getDate(), + 'stop_date' : self.stop.getDate() } def getQuoteDate(self): - if self.calendar == GREGORIAN: - return self.getGregorianQuoteDate() - elif self.calendar == JULIAN: - return self.get_quote_date(_mname,_("Julian")) - elif self.calendar == HEBREW: - return self.get_quote_date(_hmonth,_("Hebrew")) - else: - return self.get_quote_date(_fmonth,_("French")) - - def getGregorianQuoteDate(self): if self.range == 0: - return _func(self.start) + return self.start.getQuoteDate() elif self.range == -1: if self.text: return '"%s"' % self.text else: return '' else: - d1 = _func(self.start) - d2 = _func(self.stop) return _("from %(start_date)s to %(stop_date)s") % { - 'start_date' : d1, - 'stop_date' : d2 } - - def get_quote_date(self,month_map,cal_str): - if self.range == 0: - return "%s (%s)" % (self.start.display_calendar(month_map),cal_str) - elif self.range == -1: - if self.text: - return '"%s (%s)"' % (self.text,cal_str) - else: - return '' - else: - d1 = self.start.display_calendar(month_map) - d2 = self.stop.display_calendar(month_map) - return _("from %(start_date)s to %(stop_date)s (%(calendar)s)") % { - 'start_date' : d1, - 'stop_data' :d2, - 'calendar' : cal_str} + 'start_date' : self.start.getQuoteDate(), + 'stop_date' : self.stop.getQuoteDate() } def isEmpty(self): s = self.start @@ -343,62 +272,6 @@ def get_format_code(): #------------------------------------------------------------------------- class SingleDate: "Date handling" - - exact = 0 - about = 1 - before = 2 - after = 3 - - emname =[ - 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', - 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' - ] - - em2num ={ - "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, - _("abt.") : about, _("est") : about , - _("est.") : about , _("circa") : about, - _("around") : about, _("before") : before, - _("bef") : before, _("bef.") : before, - _("after") : after, _("aft.") : after, - _("aft") : after, - # And the untranslated versions for reading saved data from XML. - "abt" : about, "about" : about, - "bef" : before, "bef." : before, - "aft." : after, "abt." : about, - "est." : about, "est" : about, - "after" : after, "before": before, - "aft" : after, - } - - modifiers = '(' + \ - _("abt\.?") + '|' + \ - _("about") + '|' + \ - _("est\.?") + '|' + \ - _("circa") + '|' + \ - _("around") + '|' + \ - _("before") + '|' + \ - _("after") + '|' + \ - _("aft\.?") + '|' + \ - _("bef\.?") + \ - '|abt|aft|after|before|bef)' - - start = "^\s*" + modifiers + "?\s*" - - fmt1 = compile(start+"(\S+)(\s+\d+\s*,)?\s*([?\d]+)?\s*$", IGNORECASE) - fmt2 = compile(start+"(\d+)\.?\s+(\S+)(\s+\d+)?\s*$", IGNORECASE) - fmt3 = compile(start+r"([?\d]+)\s*[./-]\s*([?\d]+)\s*[./-]\s*([?\d]+)\s*$", - IGNORECASE) - fmt7 = compile(start+r"([?\d]+)\s*[./-]\s*([?\d]+)\s*$", IGNORECASE) - fmt4 = compile(start+"(\S+)\s+(\d+)\s*$", IGNORECASE) - fmt5 = compile(start+"(\d+)\s*$", IGNORECASE) - fmt6 = compile(start+"(\S+)\s*$", IGNORECASE) def __init__(self,source=None): if source: @@ -411,49 +284,32 @@ class SingleDate: self.month = UNDEF self.day = UNDEF self.year = UNDEF - self.mode = SingleDate.exact - self.calendar = GREGORIAN + self.mode = Calendar.EXACT + self.calendar = Calendar.Gregorian() def setMode(self,val): - if not val: - self.mode = SingleDate.exact - else: - try: - self.mode = SingleDate.m2v[string.lower(val)] - except KeyError: - raise Date.Error,val + self.mode = self.calendar.set_mode_value(val) def setMonth(self,val): if val > 14 or val < 0: self.month = UNDEF else: - self.month = val - 1 + self.month = val def setMonthVal(self,s): - try: - val = int(s) - self.month = val - 1 - except: - self.month = UNDEF + self.month = self.calendar.set_value(s) def setDayVal(self,s): - try: - val = int(s) - self.day = val - except: - self.day = UNDEF + self.day = self.calendar.set_value(s) def setYearVal(self,s): - try: - val = int(s) - self.year = val - except: + if s: + self.year = self.calendar.set_value(s) + else: self.year = UNDEF def getMonth(self): - if self.month == UNDEF: - return UNDEF - return self.month + 1 + return self.month def getMonthValid(self): return self.month != UNDEF @@ -481,17 +337,7 @@ class SingleDate: return self.year != UNDEF or self.month != UNDEF or self.day != UNDEF def setMonthStr(self,text): - try: - self.month = _m2num[string.lower(text[0:3])] - except KeyError: - self.setMonthStrEng(text) - - def setMonthStrEng(self,text): - try: - self.month = SingleDate.em2num[string.lower(text[0:3])] - except KeyError: - self.month = UNDEF - raise Date.Error,text + self.calendar.set_month_string(text) def getMonthStr(self): return _mname[self.month] @@ -539,11 +385,11 @@ class SingleDate: else: retval = "%s %d, %d" % (month,self.day,self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = _("about") + ' ' + retval - elif self.mode == SingleDate.before: + elif self.mode == Calendar.BEFORE: retval = _("before") + ' ' + retval - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = _("after") + ' ' + retval return retval @@ -568,11 +414,11 @@ class SingleDate: else: retval = str(self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = "%s %s" % (_("abt"),retval) - elif self.mode == SingleDate.before: + elif self.mode == Calendar.BEFORE: retval = "%s %s" % (_("before"),retval) - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = "%s %s" % (_("after"),retval) return retval @@ -598,11 +444,11 @@ class SingleDate: else: retval = "%d %s %d" % (self.day,string.upper(month[0:3]),self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = "%s %s" % (_("ABOUT"),retval) - elif self.mode == SingleDate.before: + elif self.mode == Calendar.BEFORE: retval = "%s %s" % (_("BEFORE"),retval) - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = "%s %s" % (_("AFTER"),retval) return retval @@ -626,11 +472,11 @@ class SingleDate: else: retval = "%d. %s %d" % (self.day,month,self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = "%s %s" % (_("ABOUT"),retval) - elif self.mode == SingleDate.before: + elif self.mode == Calendar.BEFORE: retval = "%s %s" % (_("BEFORE"),retval) - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = "%s %s" % (_("AFTER"),retval) return retval @@ -653,11 +499,11 @@ class SingleDate: else: retval = "%02d%s%02d%s%04d" % (self.month+1,sep,self.day,sep,self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = "%s %s" % (_("ABOUT"),retval) - elif self.mode == SingleDate.before: + elif self.mode == Calendar.BEFORE: retval = "%s %s" % (_("BEFORE"),retval) - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = "%s %s" % (_("AFTER"),retval) return retval @@ -682,13 +528,13 @@ class SingleDate: else: retval = "%02d%s%02d%s%02d" % (self.year,sep,self.month+1,sep,self.day) - if self.mode == SingleDate.about: - retval = "%s %s" % (_("ABOUT"),retval) + if self.mode == Calendar.ABOUT: + retval = "%s %s" % (_("about"),retval) - if self.mode == SingleDate.before: - retval = "%s %s" % (_("BEFORE"),retval) - elif self.mode == SingleDate.after: - retval = "%s %s" % (_("AFTER"),retval) + if self.mode == Calendar.BEFORE: + retval = "%s %s" % (_("before"),retval) + elif self.mode == Calendar.AFTER: + retval = "%s %s" % (_("after"),retval) return retval @@ -721,11 +567,11 @@ class SingleDate: else: retval = "%02d%s%02d%s%04d" % (self.day,sep,self.month+1,sep,self.year) - if self.mode == SingleDate.about: + if self.mode == Calendar.ABOUT: retval = "%s %s" % (_("ABOUT"),retval) - if self.mode == SingleDate.before: + if self.mode == Calendar.BEFORE: retval = "%s %s" % (_("BEFORE"),retval) - elif self.mode == SingleDate.after: + elif self.mode == Calendar.AFTER: retval = "%s %s" % (_("AFTER"),retval) return retval @@ -757,38 +603,14 @@ class SingleDate: _format7, _format8, _format9, _format10, _format11, _format12, _format13] - def display_calendar(self,month_map): - d = '' - if self.year==UNDEF: - if self.month == UNDEF: - d = "" - elif self.day == UNDEF: - d = month_map[self.month] - else: - d = "%02d %s" % (self.day,month_map[self.month]) - elif self.month == UNDEF: - d = str(self.year) - elif self.day == UNDEF: - d = "%s %d" % (month_map[self.month],self.year) - else: - d = "%02d %s %d" % (self.day,month_map[self.month],self.year) - if self.mode == SingleDate.about: - d = _("about") + ' ' + d - elif self.mode == SingleDate.before: - d = _("before") + ' ' + d - elif self.mode == SingleDate.after: - d = _("after") + ' ' + d - return d - def getDate(self): - if self.calendar == GREGORIAN: - return _func(self) - elif self.calendar == JULIAN: - return self.display_calendar(_mname) - elif self.calendar == HEBREW: - return self.display_calendar(_hmonth) + return self.calendar.display(self.year, self.month, self.day, self.mode) + + def getQuoteDate(self): + if self.year == UNDEF and self.month == UNDEF and self.day == UNDEF: + return "" else: - return self.display_calendar(_fmonth) + return self.calendar.quote_display(self.year, self.month, self.day, self.mode) def setIsoDate(self,v): data = string.split(v) @@ -799,9 +621,13 @@ class SingleDate: vals = string.split(v,'-') self.setYearVal(vals[0]) if len(vals) > 1: - self.setMonthVal(vals[1]) + self.setMonthVal(int(vals[1])-1) + else: + self.month = UNDEF if len(vals) > 2: self.setDayVal(vals[2]) + else: + self.day = UNDEF def getModeVal(self): return self.mode @@ -810,198 +636,17 @@ class SingleDate: self.mode = val def set(self,text): - if self.calendar == GREGORIAN: - self.set_gregorian(text) - elif self.calendar == JULIAN: - self.set_calendar(text,_m2num,3) - elif self.calendar == HEBREW: - self.set_calendar(text,_hmonth2num,0) - else: - self.set_calendar(text,_fmonth2num,4) - - def set_calendar(self,text,month_map,l): - match = SingleDate.fmt2.match(text) - if match: - matches = match.groups() - self.setMode(matches[0]) - monthstr = unicode(matches[2]).lower() - if l == 0: - mon = monthstr - else: - mon = monthstr[0:l] - self.setYear(int(matches[3])) - if month_map.has_key(mon): - self.setMonth(month_map[mon]+1) - else: - self.setMonth(UNDEF) - self.setDay(int(matches[1])) - return - match = SingleDate.fmt3.match(text) - if match: - matches = match.groups() - self.setMode(matches[0]) - self.setYearVal(matches[3]) - self.setMonthVal(matches[2]) - self.setDayVal(matches[1]) - return - - match = SingleDate.fmt4.match(text) - if match: - matches = match.groups() - self.setMode(matches[0]) - if l == 0: - mon = string.lower(matches[1]) - else: - mon = string.lower(matches[1])[0:l] - self.setYearVal(matches[2]) - self.setMonthStr(mon) - self.day = UNDEF - return - - match = SingleDate.fmt5.match(text) - if match: - matches = match.groups() - self.setMode(matches[0]) - self.setYearVal(matches[1]) - self.month = UNDEF - self.day = UNDEF - return - - self.year = UNDEF - self.month = UNDEF - self.day = UNDEF - - def set_gregorian(self,text): - match = SingleDate.fmt2.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - self.setMonthStr(matches[2]) - self.day = int(matches[1]) - if len(matches) == 4 and matches[3] != None: - self.setYearVal(matches[3]) - else: - self.year = UNDEF - return 1 + self.year, self.month, self.day, self.mode = self.calendar.set(text) - match = SingleDate.fmt5.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - self.month = UNDEF - self.day = UNDEF - self.year = int(matches[1]) - return 1 - - match = SingleDate.fmt7.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - if Date.entryCode == 2: - self.setMonthVal(matches[2]) - self.setYearVal(matches[1]) - else: - self.setMonthVal(matches[1]) - self.setYearVal(matches[2]) - if self.getMonth() > 13: - raise Date.Error - return 1 - - match = SingleDate.fmt3.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - if Date.entryCode == 0: - self.setMonthVal(matches[1]) - self.setDayVal(matches[2]) - self.setYearVal(matches[3]) - elif Date.entryCode == 1: - self.setMonthVal(matches[2]) - self.setDayVal(matches[1]) - self.setYearVal(matches[3]) - else: - self.setMonthVal(matches[2]) - self.setDayVal(matches[3]) - self.setYearVal(matches[1]) - return 1 - - match = SingleDate.fmt1.match(text) - if match != None: - (mode,mon,day,year) = match.groups() - self.setMode(mode) - self.setMonthStr(mon) - if day: - self.setDayVal(int(string.replace(day,',',''))) - else: - self.day = UNDEF - self.setYearVal(year) - return 1 - - match = SingleDate.fmt4.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - self.setMonthStr(matches[1]) - self.day = UNDEF - if len(matches) == 4: - self.setYearVal(matches[3]) - return 1 - - match = SingleDate.fmt6.match(text) - if match != None: - matches = match.groups() - self.setMode(matches[0]) - self.setMonthVal(matches[1]) - self.day = UNDEF - self.year = UNDEF - return 1 - - raise Date.Error,text - - def get_sdn(self): - if self.year == UNDEF: - return 0 - if self.month == UNDEF: - month = 1 - else: - month = self.month + 1 - if self.day == UNDEF: - day = 1 - else: - day = self.day - - if self.calendar == GREGORIAN: - sdn = Calendar.gregorian_to_sdn(self.year,month,day) - elif self.calendar == FRENCH: - sdn = Calendar.french_to_sdn(self.year,month,day) - if self.calendar == HEBREW: - sdn = Calendar.jewish_to_sdn(self.year,month,day) - if self.calendar == JULIAN: - sdn = Calendar.julian_to_sdn(self.year,month,day) - return sdn - def convert_to(self,val): - if val == GREGORIAN: - self.convert_calendar(Calendar.sdn_to_gregorian,val) - elif val == JULIAN: - self.convert_calendar(Calendar.sdn_to_julian,val) - elif val == HEBREW: - self.convert_calendar(Calendar.sdn_to_jewish,val) - else: - self.convert_calendar(Calendar.sdn_to_french,val) + sdn = self.calendar.get_sdn(self.year, self.month, self.day) + self.calendar = val() + (self.year, self.month, self.day) = self.calendar.get_ymd(sdn) - def convert_calendar(self,func,mode): - sdn = self.get_sdn() - (y,m,d) = func(sdn) - self.calendar = mode - if y == 0 and m == 0 and d == 0: - self.year = UNDEF - self.month = UNDEF - self.day = UNDEF - else: - self.year = y - self.month = m-1 - self.day = d + def convert_to_obj(self,val): + sdn = self.calendar.get_sdn(self.year, self.month, self.day) + self.calendar = val + (self.year, self.month, self.day) = self.calendar.get_ymd(sdn) #------------------------------------------------------------------------- # @@ -1021,7 +666,7 @@ def not_too_old(date): # #------------------------------------------------------------------------- def compare_dates(f,s): - if f.calendar != s.calendar: + if f.calendar.NAME != s.calendar.NAME: return 1 if f.range == -1 and s.range == -1: return cmp(f.text,s.text) @@ -1048,3 +693,52 @@ def compare_dates(f,s): _func = SingleDate.fmtFunc[0] + +if __name__ == "__main__": + + a = Date() + a.set("24 May 1961") + print "Gregorian : ", a.getDate() + a.set(a.getDate()) + print "Gregorian : ", a.getDate() + + a.set_calendar(Calendar.Julian) + print "Julian : ", a.getDate() + a.set(a.getDate()) + print "Julian : ", a.getDate() + + a.set_calendar(Calendar.Gregorian) + print "Gregorian : ", a.getDate() + a.set(a.getDate()) + print "Gregorian : ", a.getDate() + + a.set_calendar(Calendar.Hebrew) + print "Hebrew : ", a.getDate() + a.set(a.getDate()) + print "Hebrew : ", a.getDate() + + a.set_calendar(Calendar.Gregorian) + print "Gregorian : ", a.getDate() + a.set(a.getDate()) + print "Gregorian : ", a.getDate() + + a.set_calendar(Calendar.Persian) + print "Persian : ", a.getDate() + a.set(a.getDate()) + print "Persian : ", a.getDate() + + a.set_calendar(Calendar.Gregorian) + print "Gregorian : ", a.getDate() + a.set(a.getDate()) + print "Gregorian : ", a.getDate() + + a.set_calendar(Calendar.Islamic) + print "Islamic : ", a.getDate() + a.set(a.getDate()) + print "Islamic : ", a.getDate() + + a.set_calendar(Calendar.Gregorian) + print "Gregorian : ", a.getDate() + a.set(a.getDate()) + print "Gregorian : ", a.getDate() + diff --git a/src/DateEdit.py b/src/DateEdit.py index b87920a97..6abfc3d0d 100644 --- a/src/DateEdit.py +++ b/src/DateEdit.py @@ -67,6 +67,10 @@ class DateEdit: self.text_obj.connect('focus-out-event',self.check) self.check(None,None) + def set_calendar(self,cobj): + self.checkval.set_calendar_obj(cobj) + self.check(None,None) + def check(self,obj,val): """Called with the text box loses focus. If the string contains a valid date, sets the appropriate pixmap""" diff --git a/src/EditPerson.py b/src/EditPerson.py index fe6a74b0b..e2b1f9b38 100644 --- a/src/EditPerson.py +++ b/src/EditPerson.py @@ -103,44 +103,6 @@ class EditPerson: self.attr_delete_btn = self.top.get_widget('attr_delete_btn') self.addr_delete_btn = self.top.get_widget('addr_delete_btn') - self.top.signal_autoconnect({ - "destroy_passed_object" : self.on_cancel_edit, - "on_up_clicked" : self.on_up_clicked, - "on_down_clicked" : self.on_down_clicked, - "on_add_address_clicked" : self.on_add_addr_clicked, - "on_add_aka_clicked" : self.on_add_aka_clicked, - "on_add_attr_clicked" : self.on_add_attr_clicked, - "on_add_url_clicked" : self.on_add_url_clicked, - "on_addphoto_clicked" : self.gallery.on_add_photo_clicked, - "on_aka_delete_clicked" : self.on_aka_delete_clicked, - "on_aka_update_clicked" : self.on_aka_update_clicked, - "on_apply_person_clicked" : self.on_apply_person_clicked, - "on_edit_birth_clicked" : self.on_edit_birth_clicked, - "on_edit_death_clicked" : self.on_edit_death_clicked, - "on_delete_address_clicked" : self.on_delete_addr_clicked, - "on_delete_attr_clicked" : self.on_delete_attr_clicked, - "on_delete_event" : self.on_delete_event, - "on_delete_url_clicked" : self.on_delete_url_clicked, - "on_deletephoto_clicked" : self.gallery.on_delete_photo_clicked, - "on_edit_properties_clicked": self.gallery.popup_change_description, - "on_editperson_switch_page" : self.on_switch_page, - "on_event_add_clicked" : self.on_event_add_clicked, - "on_event_delete_clicked" : self.on_event_delete_clicked, - "on_event_update_clicked" : self.on_event_update_clicked, - "on_name_note_clicked" : self.on_name_note_clicked, - "on_ldsbap_note_clicked" : self.on_ldsbap_note_clicked, - "on_ldsendow_note_clicked" : self.on_ldsendow_note_clicked, - "on_ldsseal_note_clicked" : self.on_ldsseal_note_clicked, - "on_ldsbap_src_clicked" : self.on_ldsbap_source_clicked, - "on_ldsendow_src_clicked" : self.on_ldsendow_source_clicked, - "on_ldsseal_src_clicked" : self.on_ldsseal_source_clicked, - "on_name_source_clicked" : self.on_primary_name_source_clicked, - "on_update_address_clicked" : self.on_update_addr_clicked, - "on_update_attr_clicked" : self.on_update_attr_clicked, - "on_update_url_clicked" : self.on_update_url_clicked, - "on_web_go_clicked" : self.on_web_go_clicked, - }) - self.window = self.get_widget("editPerson") self.notes_field = self.get_widget("personNotes") self.event_name_field = self.get_widget("eventName") @@ -278,8 +240,6 @@ class EditPerson: self.is_unknown.set_active(1) self.nick.set_text(person.getNickName()) - self.update_birth_death() - self.load_person_image() # set notes data @@ -314,6 +274,52 @@ class EditPerson: self.addr_list.connect('drag_data_received', self.ad_drag_data_received) + self.bdate_check = DateEdit(self.bdate,self.get_widget("birth_stat")) + self.bdate_check.set_calendar(self.birth.getDateObj().get_calendar()) + + self.ddate_check = DateEdit(self.ddate,self.get_widget("death_stat")) + self.ddate_check.set_calendar(self.death.getDateObj().get_calendar()) + + self.top.signal_autoconnect({ + "destroy_passed_object" : self.on_cancel_edit, + "on_up_clicked" : self.on_up_clicked, + "on_down_clicked" : self.on_down_clicked, + "on_add_address_clicked" : self.on_add_addr_clicked, + "on_add_aka_clicked" : self.on_add_aka_clicked, + "on_add_attr_clicked" : self.on_add_attr_clicked, + "on_add_url_clicked" : self.on_add_url_clicked, + "on_addphoto_clicked" : self.gallery.on_add_photo_clicked, + "on_aka_delete_clicked" : self.on_aka_delete_clicked, + "on_aka_update_clicked" : self.on_aka_update_clicked, + "on_apply_person_clicked" : self.on_apply_person_clicked, + "on_edit_birth_clicked" : self.on_edit_birth_clicked, + "on_edit_death_clicked" : self.on_edit_death_clicked, + "on_delete_address_clicked" : self.on_delete_addr_clicked, + "on_delete_attr_clicked" : self.on_delete_attr_clicked, + "on_delete_event" : self.on_delete_event, + "on_delete_url_clicked" : self.on_delete_url_clicked, + "on_deletephoto_clicked" : self.gallery.on_delete_photo_clicked, + "on_edit_properties_clicked": self.gallery.popup_change_description, + "on_editperson_switch_page" : self.on_switch_page, + "on_event_add_clicked" : self.on_event_add_clicked, + "on_event_delete_clicked" : self.on_event_delete_clicked, + "on_event_update_clicked" : self.on_event_update_clicked, + "on_name_note_clicked" : self.on_name_note_clicked, + "on_ldsbap_note_clicked" : self.on_ldsbap_note_clicked, + "on_ldsendow_note_clicked" : self.on_ldsendow_note_clicked, + "on_ldsseal_note_clicked" : self.on_ldsseal_note_clicked, + "on_ldsbap_src_clicked" : self.on_ldsbap_source_clicked, + "on_ldsendow_src_clicked" : self.on_ldsendow_source_clicked, + "on_ldsseal_src_clicked" : self.on_ldsseal_source_clicked, + "on_name_source_clicked" : self.on_primary_name_source_clicked, + "on_update_address_clicked" : self.on_update_addr_clicked, + "on_update_attr_clicked" : self.on_update_attr_clicked, + "on_update_url_clicked" : self.on_update_url_clicked, + "on_web_go_clicked" : self.on_web_go_clicked, + }) + + self.update_birth_death() + self.redraw_event_list() self.redraw_attr_list() self.redraw_addr_list() @@ -459,6 +465,7 @@ class EditPerson: self.seal_stat = obj.get_data("val") def ev_drag_data_received(self,widget,context,x,y,sel_data,info,time): + print context, info, time if sel_data and sel_data.data: exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] @@ -478,8 +485,9 @@ class EditPerson: self.redraw_event_list() def ev_drag_data_get(self,widget, context, sel_data, info, time): - ev = widget.get_row_data(widget.focus_row) - + store, iter = widget.get_selection().get_selected() + ev = store.get_value(iter,4) + bits_per = 8; # we're going to pass a string pickled = pickle.dumps(ev); data = str(('pevent',self.person.getId(),pickled)); @@ -625,14 +633,12 @@ class EditPerson: self.update_birth = 0 self.update_birth_info() self.dplace.set_text(prev_dtext) - self.bdate_check = DateEdit(self.bdate,self.get_widget("birth_stat")) # Update death with new values, make sure birth values don't change if self.update_death: self.update_death = 0 self.update_death_info() self.bplace.set_text(prev_btext) - self.ddate_check = DateEdit(self.ddate,self.get_widget("death_stat")) def on_add_addr_clicked(self,obj): """Invokes the address editor to add a new address""" @@ -899,7 +905,9 @@ class EditPerson: def update_birth_death(self): self.bdate.set_text(self.birth.getDate()) self.bplace.set_text(self.birth.getPlaceName()) + self.bdate_check.set_calendar(self.birth.getDateObj().get_calendar()) self.ddate.set_text(self.death.getDate()) + self.ddate_check.set_calendar(self.death.getDateObj().get_calendar()) self.dplace.set_text(self.death.getPlaceName()) self.dplace.set_text(self.death.getPlaceName()) # self.bdate.set_position(0) diff --git a/src/EventEdit.py b/src/EventEdit.py index 1cd69990d..155729a25 100644 --- a/src/EventEdit.py +++ b/src/EventEdit.py @@ -38,6 +38,7 @@ import const import Utils import GrampsCfg import AutoComp +import Calendar from DateEdit import DateEdit from Date import compare_dates @@ -132,14 +133,17 @@ class EventEditor: }) menu = gtk.Menu() - names = [ _("Gregorian"), _("Julian"), _("Hebrew"), ("French") ] - for index in range(0,len(names)): - item = gtk.MenuItem(names[index]) - item.set_data("d",index) + index = 0 + for cobj in Calendar.calendar_names(): + item = gtk.MenuItem(cobj.TNAME) + item.set_data("d",cobj) item.connect("activate",self.on_menu_changed) item.show() menu.append(item) - menu.set_active(self.date.get_calendar()) + if self.date.get_calendar().NAME == cobj.NAME: + menu.set_active(index) + self.date_check.set_calendar(cobj()) + index = index + 1 self.calendar.set_menu(menu) def add_source(self,obj): @@ -149,9 +153,11 @@ class EventEditor: pass def on_menu_changed(self,obj): + cobj = obj.get_data("d") self.date.set(self.date_field.get_text()) - self.date.set_calendar(obj.get_data("d")) + self.date.set_calendar(cobj) self.date_field.set_text(self.date.getDate()) + self.date_check.set_calendar(cobj()) def get_place(self,field,makenew=0): text = strip(field.get_text()) diff --git a/src/FamilyView.py b/src/FamilyView.py index d35a9adba..bbb9837e8 100644 --- a/src/FamilyView.py +++ b/src/FamilyView.py @@ -266,8 +266,8 @@ class FamilyView: self.person = self.parent.active_person if not self.person: return - - n = "%s\n\tb. %s\n\td. %s" % (self.person.getPrimaryName().getName(), + + n = "%s\n\tb. %s\n\td. %s " % (self.person.getPrimaryName().getName(), self.person.getBirth().getDate(), self.person.getDeath().getDate()) self.ap_data.set_text(n,len(n)) @@ -275,6 +275,7 @@ class FamilyView: self.selected_spouse = None self.spouse_model.clear() self.child_model.clear() + self.sp_parents_model.clear() splist = self.person.getFamilyList() f = None first_family = None diff --git a/src/GrampsParser.py b/src/GrampsParser.py index 8ef5e6afd..dfc85c9e3 100644 --- a/src/GrampsParser.py +++ b/src/GrampsParser.py @@ -22,6 +22,7 @@ from RelLib import * from Date import SingleDate import string +import Calendar import Utils import xml.parsers.expat @@ -421,7 +422,10 @@ class GrampsParser: d = self.event.getDateObj() if attrs.has_key("calendar"): - d.set_calendar(int(attrs['calendar'])) + d.set_calendar_val(int(attrs['calendar'])) + + if attrs.has_key("cformat"): + d.set_calendar(Calendar.find_calendar(attrs['calendar'])) d.get_start_date().setIsoDate(attrs['start']) d.get_stop_date().setIsoDate(attrs['stop']) @@ -438,7 +442,10 @@ class GrampsParser: d = self.event.getDateObj() if attrs.has_key("calendar"): - d.set_calendar(int(attrs['calendar'])) + d.set_calendar_val(int(attrs['calendar'])) + + if attrs.has_key("cformat"): + d.set_calendar(Calendar.find_calendar(attrs['calendar'])) d.get_start_date().setIsoDate(attrs['val']) diff --git a/src/ListModel.py b/src/ListModel.py index 536a4a788..7ea06fc8c 100644 --- a/src/ListModel.py +++ b/src/ListModel.py @@ -68,6 +68,9 @@ class ListModel: self.double_click = event_func self.tree.connect('event',self.button_press) + def set_reorderable(self,order): + self.tree.set_reorderable(order) + def new_model(self): self.model = gtk.ListStore(*self.mylist) diff --git a/src/ReadXML.py b/src/ReadXML.py index 82ad58731..8c1672558 100644 --- a/src/ReadXML.py +++ b/src/ReadXML.py @@ -40,7 +40,7 @@ import gnome.ui #------------------------------------------------------------------------- from RelLib import * from GrampsParser import GrampsParser, GrampsImportParser -from QuestionDialog import ErrorDialog +from QuestionDialog import ErrorDialog, WarningDialog from intl import gettext as _ #------------------------------------------------------------------------- @@ -99,6 +99,16 @@ def importData(database, filename, callback): import traceback traceback.print_exc() return 0 + except ValueError,msg: + if str(msg)[0:16] == "Incorrect length": + WarningDialog(_("Your database has encountered an error in the library " + "that compresses the data.\nYour data should be okay, but " + "you may want to consider disabling compression.\n" + "This can be disabled in the Properties dialog.")) + else: + import DisplayTrace + DisplayTrace.DisplayTrace() + return 0 except: import DisplayTrace DisplayTrace.DisplayTrace() diff --git a/src/WriteXML.py b/src/WriteXML.py index 17bfdad6e..bd5b076ae 100644 --- a/src/WriteXML.py +++ b/src/WriteXML.py @@ -39,8 +39,8 @@ import os #------------------------------------------------------------------------- import const import GrampsCfg +import Calendar from RelLib import * -from Date import SingleDate from intl import gettext as _ from QuestionDialog import ErrorDialog @@ -65,7 +65,7 @@ def exportData(database, filename, callback): if os.path.isfile(filename): shutil.copy(filename, filename + ".bak") - compress = GrampsCfg.uncompress ==0 and _gzip_ok == 1 + compress = GrampsCfg.uncompress == 0 and _gzip_ok == 1 try: g = XmlWriter(database,callback,0,compress) @@ -454,9 +454,8 @@ class XmlWriter: if date.isEmpty(): return - cal = date.get_calendar() if cal != 0: - calstr = ' calendar="%s"' % self.fix(str(cal)) + calstr = ' cformat="%s"' % date.get_calendar().NAME else: calstr = '' @@ -469,11 +468,11 @@ class XmlWriter: mode = d1.getModeVal() dstr = d1.getIsoDate() - if mode == SingleDate.before: + if mode == Calendar.BEFORE: pref = ' type="before"' - elif mode == SingleDate.after: + elif mode == Calendar.AFTER: pref = ' type="after"' - elif mode == SingleDate.about: + elif mode == Calendar.ABOUT: pref = ' type="about"' else: pref = "" diff --git a/src/gramps_main.py b/src/gramps_main.py index 63f88c172..e3786edc2 100755 --- a/src/gramps_main.py +++ b/src/gramps_main.py @@ -886,6 +886,7 @@ class Gramps: def goto_active_person(self): if not self.active_person: + self.ptabs.set_current_page(0) return id = self.active_person.getId() if self.id2col.has_key(id): @@ -1176,7 +1177,7 @@ class Gramps: def add_to_person_list(self,person,change): key = person.getId() val = self.db.getPersonDisplay(person.getId()) - pg = val[5] + pg = unicode(val[5]) pg = pg[0] if self.DataFilter.compare(person): @@ -1346,7 +1347,7 @@ class Gramps: for key in self.db.getPersonKeys(): person = self.db.getPerson(key) val = self.db.getPersonDisplay(key) - pg = val[5] + pg = unicode(val[5]) if pg: pg = pg[0] if datacomp(person): diff --git a/src/latin_utf8.py b/src/latin_utf8.py index 0538f0464..05c44b6c6 100644 --- a/src/latin_utf8.py +++ b/src/latin_utf8.py @@ -22,6 +22,6 @@ def utf8_to_latin(s): return s.encode('iso-8859-1','replace') def latin_to_utf8(s): - return unicode(s,'latin-1') + return unicode(s) diff --git a/src/plugins/ReadGedcom.py b/src/plugins/ReadGedcom.py index c519fe47a..c63ff7c1a 100644 --- a/src/plugins/ReadGedcom.py +++ b/src/plugins/ReadGedcom.py @@ -64,7 +64,7 @@ callback = None UNEXPECTED_EOF = "Unexpected End of File" def nocnv(s): - return s + return unicode(s) photo_types = [ "jpeg", "bmp", "pict", "pntg", "tpic", "png", "gif", "jpg", "tiff", "pcx" ] @@ -1406,8 +1406,7 @@ class GedcomParser: self.gedsource = self.gedmap.get_from_source_tag(matches[2]) self.broken_conc = self.gedsource.get_conc() elif matches[1] == "CHAR": - if matches[2] == "UNICODE" or matches[2] == "UTF-8" or \ - matches[2] == "UTF8": + if matches[2] == "UNICODE" or matches[2] == "UTF-8" or matches[2] == "UTF8": self.code = UNICODE self.cnv = nocnv elif matches[2] == "ANSEL": diff --git a/src/plugins/WriteGedcom.py b/src/plugins/WriteGedcom.py index 9f774d393..05403e775 100644 --- a/src/plugins/WriteGedcom.py +++ b/src/plugins/WriteGedcom.py @@ -736,7 +736,7 @@ class GedcomWriter: else: self.g.write("1 EVEN\n") self.g.write("2 TYPE %s\n" % self.cnvtxt(name)) - self.g.write("2 PLAC %s\n" % self.cnvtxt(attr.getValue())) + self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(attr.getValue()),'\r',' ')) if attr.getNote(): self.write_long_text("NOTE",2,self.cnvtxt(attr.getNote())) for srcref in attr.getSourceRefList(): @@ -764,7 +764,7 @@ class GedcomWriter: text = addr_append(text,addr.getPostal()) text = addr_append(text,addr.getCountry()) if text: - self.g.write("2 PLAC %s\n" % text) + self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(text)),'\r',' ') if addr.getNote(): self.write_long_text("NOTE",3,self.cnvtxt(addr.getNote())) for srcref in addr.getSourceRefList(): @@ -861,7 +861,7 @@ class GedcomWriter: dateobj = event.getDateObj() self.print_date("2 DATE",dateobj) if event.getPlaceName(): - self.g.write("2 PLAC %s\n" % self.cnvtxt(event.getPlaceName())) + self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(event.getPlaceName()),'\r',' ')) if event.getCause(): self.g.write("2 CAUS %s\n" % self.cnvtxt(event.getCause())) if event.getNote(): @@ -879,7 +879,7 @@ class GedcomWriter: if ord.getTemple(): self.g.write('%d TEMP %s\n' % (index+1,ord.getTemple())) if ord.getPlaceName(): - self.g.write("2 PLAC %s\n" % self.cnvtxt(ord.getPlaceName())) + self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(ord.getPlaceName()),'\r',' ')) if ord.getStatus() != 0: self.g.write("2 STAT %s\n" % self.cnvtxt(statlist[ord.getStatus()])) if ord.getNote():