From de14d29f5024f4630056840e9451ab97d40dd8c7 Mon Sep 17 00:00:00 2001 From: Don Allingham Date: Tue, 31 Dec 2002 02:22:04 +0000 Subject: [PATCH] Updated for calendar handling svn: r1234 --- gramps2/NEWS | 10 +- gramps2/configure | 2 +- gramps2/configure.in | 2 +- gramps2/example/gramps/data.gramps | Bin 3773 -> 3745 bytes gramps2/gramps.spec | 2 +- gramps2/src/Calendar.py | 777 ++++++++++++++++++++++++++--- gramps2/src/const.py | 2 +- 7 files changed, 730 insertions(+), 65 deletions(-) diff --git a/gramps2/NEWS b/gramps2/NEWS index b4976c73f..c4d60f739 100644 --- a/gramps2/NEWS +++ b/gramps2/NEWS @@ -1,3 +1,11 @@ +Version 0.9.0-pre8 +* Improved support for calendar formats +* Improved UTF-8 support +* Tabs for person list based off name first letter of the surname. Dynamically + created +* More features implemented +* Many bug fixes + Version 0.7.3 * New Russian (Alex Roitman) and Danish (Lars Lundin) translations. GRAMPS now supports English, Italian, German, French, Spanish, @@ -359,4 +367,4 @@ Version 0.1.2 * Fixed a bug in the relationship calculator that caused a traceback when the person selected was a direct ancestor of the active person. * Added the suffix field to the alternate name entry on the Edit Person - form. \ No newline at end of file + form. diff --git a/gramps2/configure b/gramps2/configure index 67071b2c2..ed0fe4c85 100755 --- a/gramps2/configure +++ b/gramps2/configure @@ -1567,7 +1567,7 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -RELEASE=pre7 +RELEASE=pre8 VERSIONSTRING=$VERSION if test x"$RELEASE" != "x" diff --git a/gramps2/configure.in b/gramps2/configure.in index 10a9f8fc7..eaa602596 100644 --- a/gramps2/configure.in +++ b/gramps2/configure.in @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl May need to run automake && aclocal first AC_INIT(src/gramps.py) AM_INIT_AUTOMAKE(gramps, 0.9.0) -RELEASE=pre7 +RELEASE=pre8 VERSIONSTRING=$VERSION if test x"$RELEASE" != "x" diff --git a/gramps2/example/gramps/data.gramps b/gramps2/example/gramps/data.gramps index 3f2d5ce4b1f2702220f9dddeb27989302cd8d6b4..773b7b992e45481b6a81bbbb768873e140c2c584 100644 GIT binary patch delta 3372 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 C4}IJK delta 3402 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 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(self,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(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 + # 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(self,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 set_sdn(self,sdn): + """Converts an SDN number to a Julian calendar date""" + + if sdn <= SDN_OFFSET : + return (0,0,0) + + inputDay = sdn - 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 get_sdn(self,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 + SDN_OFFSET + +#------------------------------------------------------------------------- +# +# Persian +# +#------------------------------------------------------------------------- +class Persian(Calendar): + """Persian Calendar""" + + PERSIAN_EPOCH = 1948320.5; + + def get_sdn(self,year, month, day): + if year >= 0: + epbase = year - 474 + else: + epbase = year - 473 + + epyear = 474 + epbase % 2820 + + if month <= 7: + v1 = (month - 1) * 31 + else: + v1 = ((month - 1) * 30) + 6 + v2 = math.floor(((epyear * 682) - 110) / 2816) + v3 = (epyear - 1) * 365 + day + v4 = math.floor(epbase / 2820) * 1029983 + + return int(math.ceil(v1 + v2 + v3 + v4 + PERSIAN_EPOCH - 1)) + + def set_sdn(self,sdn): + sdn = math.floor(sdn) + 0.5 + + depoch = sdn - persian_to_sdn(475, 1, 1) + cycle = math.floor(depoch / 1029983) + cyear = depoch % 1029983 + if cyear == 1029982: + ycycle = 2820 + else: + aux1 = math.floor(cyear / 366) + aux2 = cyear % 366 + ycycle = math.floor(((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1; + + year = ycycle + (2820 * cycle) + 474 + if year <= 0: + year = year - 1; + + yday = sdn - persian_to_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 + return (int(year), int(month), int(day)) + +#------------------------------------------------------------------------- +# +# FrenchRepublic +# +#------------------------------------------------------------------------- +class FrenchRepublic(Calendar): + """French Republic Calendar""" + + SDN_OFFSET = 2375474 + DAYS_PER_4_YEARS = 1461 + DAYS_PER_MONTH = 30 + FIRST_VALID = 2375840 + LAST_VALID = 2380952 + + 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 + + def set_sdn(self,sdn): + """Converts an SDN number to a French Republican Calendar date""" + if (sdn < FIRST_VALID or sdn > 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 + return (year,month,day) + +#------------------------------------------------------------------------- +# +# Gregorian +# +#------------------------------------------------------------------------- +class Gregorian(Calendar): + """Gregorian Calendar""" + + SDN_OFFSET = 32045 + DAYS_PER_5_MONTHS = 153 + DAYS_PER_4_YEARS = 1461 + DAYS_PER_400_YEARS = 146097 + + def get_sdn(self,sdn): + """Converts an SDN number to a gregorial date""" + if sdn <= 0: + return (0,0,0) + + temp = (sdn + SDN_OFFSET) * 4 - 1 + + # Calculate the century (year/100) + century = temp / 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 + + # 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 + + # 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 set_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: + 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) * DAYS_PER_400_YEARS) / 4 + + ((year % 100) * DAYS_PER_4_YEARS) / 4 + + (month * DAYS_PER_5_MONTHS + 2) / 5 + + iday + - SDN_OFFSET ); + +#------------------------------------------------------------------------- +# +# Julian +# +#------------------------------------------------------------------------- +class Julian(Calendar): + """Julian calendar""" + + SDN_OFFSET = 32083 + DAYS_PER_5_MONTHS = 153 + DAYS_PER_4_YEARS = 1461 + + def get_sdn(self,sdn): + """Converts an SDN number to a Julian date""" + if sdn <= 0 : + return (0,0,0) + + temp = (sdn + 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 + + # 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; + + # 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 set_sdn(self,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*DAYS_PER_4_YEARS)/4 + (month*DAYS_PER_5_MONTHS+2)/5 + iday - SDN_OFFSET + +#------------------------------------------------------------------------- +# +# Islamic +# +#------------------------------------------------------------------------- +class Islamic(Calendar): + """Islamic calendar""" + + ISLAMIC_EPOCH = 1948439.5 + + def set_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)) + + def get_sdn(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) + return (year,month,day) + #------------------------------------------------------------------------- # # Tasks # #------------------------------------------------------------------------- +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): @@ -165,64 +871,6 @@ def gregorian_to_sdn(iyear,imonth,iday): + iday - _GR_SDN_OFFSET ); - -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 Tishri1(metonicYear, moladDay, moladHalakim): tishri1 = moladDay @@ -511,3 +1159,12 @@ def jewish_to_sdn(year, month, day): else: return 0 return sdn + _H_SDN_OFFSET + +if __name__ == "__main__": + + e = Gregorian() + print e.format(1992,12,2,Date.SingleDate.exact) + print e.format(2002,1,28,Date.SingleDate.about) + + f = Hebrew() + print f.format(1992,12,2,Date.SingleDate.exact) diff --git a/gramps2/src/const.py b/gramps2/src/const.py index 4f4f115c3..239e290dd 100644 --- a/gramps2/src/const.py +++ b/gramps2/src/const.py @@ -100,7 +100,7 @@ startup = 1 # #------------------------------------------------------------------------- progName = "GRAMPS" -version = "0.9.0-pre7" +version = "0.9.0-pre8" copyright = "© 2001-2002 Donald N. Allingham" authors = ["Donald N. Allingham", "David Hampton","Donald A. Peterson"] comments = _("GRAMPS (Genealogical Research and Analysis "