146 lines
4.2 KiB
Python
146 lines
4.2 KiB
Python
# Functions for dealing with dates and times.
|
|
|
|
import re
|
|
import string
|
|
|
|
def timestringtoseconds(text, separator = ':'):
|
|
inputList = string.split(string.strip(text), separator)
|
|
if len(inputList) != 3:
|
|
raise ValueError, 'invalid value: ' + text
|
|
|
|
sign = 1
|
|
if len(inputList[0]) > 0 and inputList[0][0] in ('+', '-'):
|
|
if inputList[0][0] == '-':
|
|
sign = -1
|
|
inputList[0] = inputList[0][1:]
|
|
|
|
if re.search('[^0-9]', string.join(inputList, '')) is not None:
|
|
raise ValueError, 'invalid value: ' + text
|
|
|
|
hour = string.atoi(inputList[0])
|
|
minute = string.atoi(inputList[1])
|
|
second = string.atoi(inputList[2])
|
|
|
|
if minute >= 60 or second >= 60:
|
|
raise ValueError, 'invalid value: ' + text
|
|
return sign * (hour * 60 * 60 + minute * 60 + second)
|
|
|
|
_year_pivot = 50
|
|
_century = 2000
|
|
|
|
def setyearpivot(pivot, century = None):
|
|
global _year_pivot
|
|
global _century
|
|
oldvalues = (_year_pivot, _century)
|
|
_year_pivot = pivot
|
|
if century is not None:
|
|
_century = century
|
|
return oldvalues
|
|
|
|
def datestringtojdn(text, format = 'ymd', separator = '/'):
|
|
inputList = string.split(string.strip(text), separator)
|
|
if len(inputList) != 3:
|
|
raise ValueError, 'invalid value: ' + text
|
|
|
|
if re.search('[^0-9]', string.join(inputList, '')) is not None:
|
|
raise ValueError, 'invalid value: ' + text
|
|
formatList = list(format)
|
|
day = string.atoi(inputList[formatList.index('d')])
|
|
month = string.atoi(inputList[formatList.index('m')])
|
|
year = string.atoi(inputList[formatList.index('y')])
|
|
|
|
if _year_pivot is not None:
|
|
if year >= 0 and year < 100:
|
|
if year <= _year_pivot:
|
|
year = year + _century
|
|
else:
|
|
year = year + _century - 100
|
|
|
|
jdn = ymdtojdn(year, month, day)
|
|
if jdntoymd(jdn) != (year, month, day):
|
|
raise ValueError, 'invalid value: ' + text
|
|
return jdn
|
|
|
|
def _cdiv(a, b):
|
|
# Return a / b as calculated by most C language implementations,
|
|
# assuming both a and b are integers.
|
|
|
|
if a * b > 0:
|
|
return a / b
|
|
else:
|
|
return -(abs(a) / abs(b))
|
|
|
|
def ymdtojdn(year, month, day, julian = -1, papal = 1):
|
|
|
|
# set Julian flag if auto set
|
|
if julian < 0:
|
|
if papal: # Pope Gregory XIII's decree
|
|
lastJulianDate = 15821004L # last day to use Julian calendar
|
|
else: # British-American usage
|
|
lastJulianDate = 17520902L # last day to use Julian calendar
|
|
|
|
julian = ((year * 100L) + month) * 100 + day <= lastJulianDate
|
|
|
|
if year < 0:
|
|
# Adjust BC year
|
|
year = year + 1
|
|
|
|
if julian:
|
|
return 367L * year - _cdiv(7 * (year + 5001L + _cdiv((month - 9), 7)), 4) + \
|
|
_cdiv(275 * month, 9) + day + 1729777L
|
|
else:
|
|
return (day - 32076L) + \
|
|
_cdiv(1461L * (year + 4800L + _cdiv((month - 14), 12)), 4) + \
|
|
_cdiv(367 * (month - 2 - _cdiv((month - 14), 12) * 12), 12) - \
|
|
_cdiv((3 * _cdiv((year + 4900L + _cdiv((month - 14), 12)), 100)), 4) + \
|
|
1 # correction by rdg
|
|
|
|
def jdntoymd(jdn, julian = -1, papal = 1):
|
|
|
|
# set Julian flag if auto set
|
|
if julian < 0:
|
|
if papal: # Pope Gregory XIII's decree
|
|
lastJulianJdn = 2299160L # last jdn to use Julian calendar
|
|
else: # British-American usage
|
|
lastJulianJdn = 2361221L # last jdn to use Julian calendar
|
|
|
|
julian = (jdn <= lastJulianJdn);
|
|
|
|
x = jdn + 68569L
|
|
if julian:
|
|
x = x + 38
|
|
daysPer400Years = 146100L
|
|
fudgedDaysPer4000Years = 1461000L + 1
|
|
else:
|
|
daysPer400Years = 146097L
|
|
fudgedDaysPer4000Years = 1460970L + 31
|
|
|
|
z = _cdiv(4 * x, daysPer400Years)
|
|
x = x - _cdiv((daysPer400Years * z + 3), 4)
|
|
y = _cdiv(4000 * (x + 1), fudgedDaysPer4000Years)
|
|
x = x - _cdiv(1461 * y, 4) + 31
|
|
m = _cdiv(80 * x, 2447)
|
|
d = x - _cdiv(2447 * m, 80)
|
|
x = _cdiv(m, 11)
|
|
m = m + 2 - 12 * x
|
|
y = 100 * (z - 49) + y + x
|
|
|
|
# Convert from longs to integers.
|
|
yy = int(y)
|
|
mm = int(m)
|
|
dd = int(d)
|
|
|
|
if yy <= 0:
|
|
# Adjust BC years.
|
|
yy = yy - 1
|
|
|
|
return (yy, mm, dd)
|
|
|
|
def stringtoreal(text, separator = '.'):
|
|
if separator != '.':
|
|
if string.find(text, '.') >= 0:
|
|
raise ValueError, 'invalid value: ' + text
|
|
index = string.find(text, separator)
|
|
if index >= 0:
|
|
text = text[:index] + '.' + text[index + 1:]
|
|
return string.atof(text)
|