| 1 | # Functions for dealing with dates and times. |
| 2 | |
| 3 | import re |
| 4 | import string |
| 5 | |
| 6 | def timestringtoseconds(text, separator = ':'): |
| 7 | inputList = string.split(string.strip(text), separator) |
| 8 | if len(inputList) != 3: |
| 9 | raise ValueError, 'invalid value: ' + text |
| 10 | |
| 11 | sign = 1 |
| 12 | if len(inputList[0]) > 0 and inputList[0][0] in ('+', '-'): |
| 13 | if inputList[0][0] == '-': |
| 14 | sign = -1 |
| 15 | inputList[0] = inputList[0][1:] |
| 16 | |
| 17 | if re.search('[^0-9]', string.join(inputList, '')) is not None: |
| 18 | raise ValueError, 'invalid value: ' + text |
| 19 | |
| 20 | hour = string.atoi(inputList[0]) |
| 21 | minute = string.atoi(inputList[1]) |
| 22 | second = string.atoi(inputList[2]) |
| 23 | |
| 24 | if minute >= 60 or second >= 60: |
| 25 | raise ValueError, 'invalid value: ' + text |
| 26 | return sign * (hour * 60 * 60 + minute * 60 + second) |
| 27 | |
| 28 | _year_pivot = 50 |
| 29 | _century = 2000 |
| 30 | |
| 31 | def setyearpivot(pivot, century = None): |
| 32 | global _year_pivot |
| 33 | global _century |
| 34 | oldvalues = (_year_pivot, _century) |
| 35 | _year_pivot = pivot |
| 36 | if century is not None: |
| 37 | _century = century |
| 38 | return oldvalues |
| 39 | |
| 40 | def datestringtojdn(text, format = 'ymd', separator = '/'): |
| 41 | inputList = string.split(string.strip(text), separator) |
| 42 | if len(inputList) != 3: |
| 43 | raise ValueError, 'invalid value: ' + text |
| 44 | |
| 45 | if re.search('[^0-9]', string.join(inputList, '')) is not None: |
| 46 | raise ValueError, 'invalid value: ' + text |
| 47 | formatList = list(format) |
| 48 | day = string.atoi(inputList[formatList.index('d')]) |
| 49 | month = string.atoi(inputList[formatList.index('m')]) |
| 50 | year = string.atoi(inputList[formatList.index('y')]) |
| 51 | |
| 52 | if _year_pivot is not None: |
| 53 | if year >= 0 and year < 100: |
| 54 | if year <= _year_pivot: |
| 55 | year = year + _century |
| 56 | else: |
| 57 | year = year + _century - 100 |
| 58 | |
| 59 | jdn = ymdtojdn(year, month, day) |
| 60 | if jdntoymd(jdn) != (year, month, day): |
| 61 | raise ValueError, 'invalid value: ' + text |
| 62 | return jdn |
| 63 | |
| 64 | def _cdiv(a, b): |
| 65 | # Return a / b as calculated by most C language implementations, |
| 66 | # assuming both a and b are integers. |
| 67 | |
| 68 | if a * b > 0: |
| 69 | return a / b |
| 70 | else: |
| 71 | return -(abs(a) / abs(b)) |
| 72 | |
| 73 | def ymdtojdn(year, month, day, julian = -1, papal = 1): |
| 74 | |
| 75 | # set Julian flag if auto set |
| 76 | if julian < 0: |
| 77 | if papal: # Pope Gregory XIII's decree |
| 78 | lastJulianDate = 15821004L # last day to use Julian calendar |
| 79 | else: # British-American usage |
| 80 | lastJulianDate = 17520902L # last day to use Julian calendar |
| 81 | |
| 82 | julian = ((year * 100L) + month) * 100 + day <= lastJulianDate |
| 83 | |
| 84 | if year < 0: |
| 85 | # Adjust BC year |
| 86 | year = year + 1 |
| 87 | |
| 88 | if julian: |
| 89 | return 367L * year - _cdiv(7 * (year + 5001L + _cdiv((month - 9), 7)), 4) + \ |
| 90 | _cdiv(275 * month, 9) + day + 1729777L |
| 91 | else: |
| 92 | return (day - 32076L) + \ |
| 93 | _cdiv(1461L * (year + 4800L + _cdiv((month - 14), 12)), 4) + \ |
| 94 | _cdiv(367 * (month - 2 - _cdiv((month - 14), 12) * 12), 12) - \ |
| 95 | _cdiv((3 * _cdiv((year + 4900L + _cdiv((month - 14), 12)), 100)), 4) + \ |
| 96 | 1 # correction by rdg |
| 97 | |
| 98 | def jdntoymd(jdn, julian = -1, papal = 1): |
| 99 | |
| 100 | # set Julian flag if auto set |
| 101 | if julian < 0: |
| 102 | if papal: # Pope Gregory XIII's decree |
| 103 | lastJulianJdn = 2299160L # last jdn to use Julian calendar |
| 104 | else: # British-American usage |
| 105 | lastJulianJdn = 2361221L # last jdn to use Julian calendar |
| 106 | |
| 107 | julian = (jdn <= lastJulianJdn); |
| 108 | |
| 109 | x = jdn + 68569L |
| 110 | if julian: |
| 111 | x = x + 38 |
| 112 | daysPer400Years = 146100L |
| 113 | fudgedDaysPer4000Years = 1461000L + 1 |
| 114 | else: |
| 115 | daysPer400Years = 146097L |
| 116 | fudgedDaysPer4000Years = 1460970L + 31 |
| 117 | |
| 118 | z = _cdiv(4 * x, daysPer400Years) |
| 119 | x = x - _cdiv((daysPer400Years * z + 3), 4) |
| 120 | y = _cdiv(4000 * (x + 1), fudgedDaysPer4000Years) |
| 121 | x = x - _cdiv(1461 * y, 4) + 31 |
| 122 | m = _cdiv(80 * x, 2447) |
| 123 | d = x - _cdiv(2447 * m, 80) |
| 124 | x = _cdiv(m, 11) |
| 125 | m = m + 2 - 12 * x |
| 126 | y = 100 * (z - 49) + y + x |
| 127 | |
| 128 | # Convert from longs to integers. |
| 129 | yy = int(y) |
| 130 | mm = int(m) |
| 131 | dd = int(d) |
| 132 | |
| 133 | if yy <= 0: |
| 134 | # Adjust BC years. |
| 135 | yy = yy - 1 |
| 136 | |
| 137 | return (yy, mm, dd) |
| 138 | |
| 139 | def stringtoreal(text, separator = '.'): |
| 140 | if separator != '.': |
| 141 | if string.find(text, '.') >= 0: |
| 142 | raise ValueError, 'invalid value: ' + text |
| 143 | index = string.find(text, separator) |
| 144 | if index >= 0: |
| 145 | text = text[:index] + '.' + text[index + 1:] |
| 146 | return string.atof(text) |