diff -r a721966779be -r cba9f175da2d embedded/mx/DateTime/mxDateTime_python.py --- a/embedded/mx/DateTime/mxDateTime_python.py Thu May 07 16:33:22 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,614 +0,0 @@ -""" - Python implementation courtesy of Drew Csillag (StarMedia Network, Inc.) - - This version has been somewhat modified by MAL. It is still fairly - rough though and not necessarily high performance... - - XXX Still needs testing and checkup !!! - - WARNING: Using this file is only recommended if you really must - use it for some reason. It is not being actively maintained ! - -""" - -__version__ = '1.2.0 [Python]' - -import time,types,exceptions,math - -### Errors - -class Error(exceptions.StandardError): - pass - -class RangeError(Error): - pass - -### Constants (internal use only) - -month_offset=( - (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365), - (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366), - ) - -days_in_month=( - (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), - (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), - ) - -### Helpers - -def _IS_LEAPYEAR(d): - return ((d.year % 4 == 0) - and ( - (d.year % 100 != 0) - or (d.year % 400 == 0) - ) - ) - -def _YEAROFFSET(d): - return ( - (d.year - 1) * 365 - + (d.year - 1) / 4 - - (d.year - 1) / 100 - + (d.year - 1) / 400 - ) - -class _EmptyClass: - pass - -def createEmptyObject(Class, - _EmptyClass=_EmptyClass): - - o = _EmptyClass() - o.__class__ = Class - return o - -### DateTime class - -class DateTime: - - def __init__(self, year, month=1, day=1, hour=0, minute=0, second=0.0): - - second=1.0 * second - if month <= 0: - raise RangeError, "year out of range (>0)" - - #calculate absolute date - leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0)) - - #Negative values indicate days relative to the years end - if month < 0: - month = month + 13 - - if not (month >= 1 and month <= 12): - raise RangeError, "month out of range (1-12)" - - #Negative values indicate days relative to the months end - if (day < 0): - day = day + days_in_month[leap][month - 1] + 1; - - if not (day >= 1 and day <= days_in_month[leap][month - 1]): - raise RangeError, "day out of range" - - year = year - 1 - yearoffset = year * 365 + year / 4 - year / 100 + year / 400 - year = year + 1 - absdate = day + month_offset[leap][month - 1] + yearoffset; - - self.absdate = absdate - self.year = year - self.month = month - self.day = day - self.day_of_week = (absdate - 1) % 7 - self.day_of_year = absdate - yearoffset - self.days_in_month = days_in_month[leap][month - 1] - comdate = absdate - 693594 - - if not (hour >=0 and hour <= 23): - raise RangeError, "hour out of range (0-23)" - if not (minute >= 0 and minute <= 59): - raise RangeError, "minute out of range (0-59)" - if not (second >= 0.0 and - (second < 60.0 or - (hour == 23 and minute == 59 and second < 61.0))): - raise RangeError, "second out of range (0.0 - <60.0; <61.0 for 23:59)" - - self.abstime = (hour * 3600 + minute * 60) + second - self.hour = hour - self.minute = minute - self.second = second - self.dst = -1 - self.tz = "???" - self.is_leapyear = leap - self.yearoffset = yearoffset - self.iso_week = (self.year, self.day, self.day_of_week) - - if comdate < 0.0: - comdate = comdate - self.abstime / 86400.0 - else: - comdate = comdate + self.abstime / 86400.0 - - self.comdate = comdate - - def COMDate(self): - return self.comdate - - def __str__(self): - return "%04d-%02d-%02d %02d:%02d:%05.2f" % ( - self.year, self.month, self.day, self.hour, self.minute, - self.second) - - def __getattr__(self, attr): - if attr == 'mjd': - return (self - mjd0).days - elif attr == 'jdn': - return (self - jdn0).days - elif attr == 'tjd': - return (self - jdn0).days % 10000 - elif attr == 'tjd_myriad': - return int((self - jdn0).days) / 10000 + 240 - elif attr == 'absdays': - return self.absdate - 1 + self.abstime / 86400.0 - else: - try: - return self.__dict__[attr] - except: - raise AttributeError, attr - - def __mul__(self, other): - raise TypeError, "bad operand type(s) for *" - - def __div__(self, other): - raise TypeError, "bad operand type(s) for /" - - def strftime(self, format_string="%c"): - "localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)" - # The map prevents a deprecation warning on Python 2.5.1 (Mac) - # DeprecationWarning: integer argument expected, got float - items = [int(item) for item in self.tuple()] - return time.strftime(format_string, items) - - # Alias - Format = strftime - - def tuple(self): - return (self.year, self.month, self.day, self.hour, self.minute, - self.second, self.day_of_week, self.day_of_year, -1) - #return time.localtime(self.ticks()) - - def absvalues(self): - return self.absdate, self.abstime - - def __float__(self): - return self.ticks() - - def __int__(self): - return int(self.ticks) - - def ticks(self, offset=0.0, dst=-1): - tticks=time.mktime(self.year, self.month, self.day, self.hour, - self.minute, self.second, self.day_of_week, 0, dst) - if tticks == -1: - raise OverflowError, "cannot convert value to a time value" - ticks = (1.0*tticks) + (self.abstime - int(self.abstime)) - offset - return ticks - - def gmticks(self, offset=0.0): - from mx.DateTime import tz_offset - return (self-tz_offset(self)).ticks() - - def gmtoffset(self): - gmtime = DateTime(*time.gmtime()[:6]) - return - (now() - gmtime) - - def __repr__(self): - return ""% ( - self.year, self.month, self.day, self.hour, self.minute, - self.second, id(self)) - - def __cmp__(self, other, - cmp=cmp): - - if isinstance(other,DateTime): - cmpdate = cmp(self.absdate,other.absdate) - if cmpdate == 0: - return cmp(self.abstime,other.abstime) - else: - return cmpdate - elif type(other) == types.NoneType: - return -1 - elif type(other) == types.StringType: - return -1 - elif type(other) in (types.FloatType, types.LongType, types.IntType): - return 1 - return -1 - - def __hash__(self): - return hash(self.tuple()) - - def __add__(self, other): - abstime=self.abstime - absdate=self.absdate - - didadd=0 - - if type(other) == types.InstanceType: - if other.__class__ == DateTimeDelta: - abstime = abstime + other.seconds - didadd=1 - elif other.__class__ == DateTime: - raise TypeError, "DateTime + DateTime is not supported" - else: - return other.__class__.__radd__(other, self) - - elif type(other) == types.IntType or type(other) == types.FloatType: - abstime = abstime + other * 86400.0 - didadd=1 - - if not didadd: - raise TypeError, "cannot add these two types" - - if abstime >= 86400.0: - days = abstime / 86400.0 - absdate = absdate + days - abstime = abstime - (86400.0 * int(days)) - #print "absdate, abstime = ", absdate, abstime - elif abstime < 0.0: - days = int(((-abstime - 1) / 86400.0)) + 1 - #days = int(-abstime / 86400.0) - absdate = absdate - days - abstime = abstime + 86400.0 * int(days) - - if absdate < 1: - raise RangeError, "underflow while adding" - - return DateTimeFromAbsDateTime(absdate, abstime) - - def __radd__(self, other): - return DateTime.__add__(other, self) - - def __sub__(self, other): - abstime=self.abstime - absdate=self.absdate - - didsub=0 - if type(other) == types.InstanceType: - if other.__class__ == DateTimeDelta: - abstime = abstime - other.seconds - didsub = 1 - elif other.__class__ == DateTime: - absdate = absdate - other.absdate - abstime = abstime - other.abstime - return DateTimeDelta(absdate,0.0,0.0,abstime) - else: - return other.__rsub__(self) - - elif type(other) == types.IntType or type(other) == types.FloatType: - abstime = abstime - other * 86400.0; - didsub=1 - - if not didsub: - raise TypeError, "cannot subtract these two types" - - if abstime >= 86400.0: - days = abstime / 86400.0 - absdate = absdate + days - abstime = abstime - (86400.0 * days) - #print "absdate, abstime = ", absdate, abstime - elif abstime < 0.0: - #print "abstime < 0" - days = int( ((-abstime - 1) / 86400.0) + 1) - #days = -abstime / 86400.0 - absdate = absdate - int(days) - abstime = (1.0*abstime) + (86400.0 * days) - #print "absdate, abstime", absdate, abstime - if absdate < 1: - raise RangeError, "underflow while adding" - - return DateTimeFromAbsDateTime(absdate, abstime) - -# Constants -mjd0 = DateTime(1858, 11, 17) -jdn0 = DateTime(-4713, 1, 1, 12, 0, 0.0) - -# Other DateTime constructors - -def DateTimeFromCOMDate(comdate): - - absdate = int(comdate) - abstime = (comdate - float(absdate)) * 86400.0 - if abstime < 0.0: - abstime = -abstime - absdate = absdate + 693594; - dt = DateTimeFromAbsDateTime(absdate, abstime) - dt.comdate = comdate - return dt - -def DateTimeFromAbsDateTime(absdate, abstime): - - # Create the object without calling its default constructor - dt = createEmptyObject(DateTime) - - # Init. the object - abstime=1.0 * abstime - if abstime < 0 and abstime > -0.001: abstime = 0.0 - if not (absdate > 0): - raise RangeError, "absdate out of range (>0)" - if not (abstime >= 0.0 and abstime <= 86400.0): - raise RangeError, "abstime out of range (0.0 - 86400.0) <%s>" % abstime - - dt.absdate=absdate - dt.abstime=abstime - - #calculate com date - comdate = 1.0 * (dt.absdate - 693594) - if comdate < 0.0: - comdate = comdate - dt.abstime / 86400.0 - else: - comdate = comdate + dt.abstime / 86400.0 - dt.comdate = comdate - - #calculate the date - #print "absdate=", absdate - year = int((1.0 * absdate) / 365.2425) - - #newApproximation: - while 1: - #print "year=", year - yearoffset = year * 365 + year / 4 - year / 100 + year / 400 - #print "yearoffset=", yearoffset - #print "absdate=", absdate - if yearoffset >= absdate: - year = year - 1 - #print "year = ", year - continue #goto newApproximation - - year = year + 1 - leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0)) - dayoffset = absdate - yearoffset - #print "dayoffset=", dayoffset - if dayoffset > 365 and leap == 0: - #print "dayoffset=", dayoffset - continue #goto newApproximation - - monthoffset = month_offset[leap] - for month in range(1, 13): - if monthoffset[month] >= dayoffset: - break - dt.year = year - dt.month = month - dt.day = dayoffset - month_offset[leap][month-1] - dt.day_of_week = (dt.absdate - 1) % 7 - dt.day_of_year = dayoffset - break - - #calculate the time - inttime = int(abstime) - hour = inttime / 3600 - minute = (inttime % 3600) / 60 - second = abstime - 1.0 * (hour*3600 + minute*60) - dt.hour = hour; - dt.minute = minute; - dt.second = second; - dt.days_in_month = days_in_month[leap][month - 1] - dt.dst = -1 - dt.tz = "???" - dt.is_leapyear = leap - dt.yearoffset = yearoffset - return dt - -def now( - time=time.time,float=float,localtime=time.localtime, - round=round,int=int,DateTime=DateTime,floor=math.floor): - ticks = time() - Y,M,D,h,m,s = localtime(ticks)[:6] - s = s + (ticks - floor(ticks)) - return DateTime(Y,M,D,h,m,s) - -def utc( - time=time.time,float=float,gmtime=time.gmtime, - round=round,int=int,DateTime=DateTime,floor=math.floor): - - ticks = time() - Y,M,D,h,m,s = gmtime(ticks)[:6] - s = s + (ticks - floor(ticks)) - return DateTime(Y,M,D,h,m,s) - -# Aliases -Date = Timestamp = DateTime - -# XXX Calendars are not supported: -def notSupported(*args,**kws): - raise Error,'calendars are not supported by the Python version of mxDateTime' -JulianDateTime = notSupported - -### DateTimeDelta class - -class DateTimeDelta: - - def __init__(self, days=0, hours=0, minutes=0, seconds=0): - - seconds = seconds + (days * 86400.0 + hours * 3600.0 + minutes * 60.0) - self.seconds = seconds - if seconds < 0.0: - seconds = -seconds - day = long(seconds / 86400.0) - seconds = seconds - (86400.0 * day) - wholeseconds = int(seconds) - hour = wholeseconds / 3600 - minute = (wholeseconds % 3600) / 60 - second = seconds - (hour * 3600.0 + minute * 60.0) - self.day = day - self.hour = hour - self.minute = minute - self.second = second - seconds=self.seconds - self.minutes = seconds / 60.0 - self.hours = seconds / 3600.0 - self.days = seconds / 86400.0 - - def __str__(self): - if self.day != 0: - if self.seconds >= 0.0: - r="%s:%02d:%02d:%05.2f" % ( - self.day, self.hour, self.minute, self.second) - else: - r="-%s:%02d:%02d:%05.2f" % ( - self.day, self.hour, self.minute, self.second) - else: - if self.seconds >= 0.0: - r="%02d:%02d:%05.2f" % (self.hour, self.minute, self.second) - else: - r="-%02d:%02d:%05.2f" % (self.hour, self.minute, self.second) - return r - - def absvalues(self): - days=self.seconds / 86400 - seconds=self.seconds - (days * 86400.0) - return days, seconds - - def tuple(self): - return (self.day, self.hour, self.minute, self.second) - - def strftime(self, format_string): - raise NotImplementedError - - def __int__(self): - return int(self.seconds) - - def __float__(self): - return self.seconds - - def __cmp__(self, other, accuracy=0.0): - if (type(other) == types.InstanceType - and other.__class__ == DateTimeDelta): - - diff=self.seconds - other.seconds - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - elif type(other) == types.FloatType: - diff=self.seconds - other - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - elif type(other) == types.IntType: - diff=self.seconds - other - if abs(diff) > accuracy: - if diff > 0: return 1 - return -1 - - return 0 - - def __getattr__(self, attr): - seconds=self.__dict__['seconds'] - if attr in ('hour', 'minute', 'second', 'day'): - if seconds >= 0.0: - return self.__dict__[attr] - else: - return -self.__dict__[attr] - else: - try: - return self.__dict__[attr] - except: - raise AttributeError, attr - - def __div__(self, other): - if type(other) in (types.IntType, types.FloatType): - return DateTimeDelta(0.0,0.0,0.0,self.seconds / other) - elif (type(other) == types.InstanceType - and isinstance(other,DateTimeDelta)): - return DateTimeDelta(0.0,0.0,0.0,self.seconds / other.seconds) - raise TypeError, "bad operand types for /" - - def __mul__(self, other): - if type(other) == types.IntType or type(other) == types.FloatType: - return DateTimeDelta(0.0,0.0,0.0,self.seconds * other) - else: - #print "type", type(other) - raise TypeError, "cannot multiply these two types" - - def __rmul__(self, other): - return self.__mul__(other) - - def __neg__(self): - return DateTimeDelta(0.0,0.0,0.0,-self.seconds) - - def __repr__(self): - if self.day != 0: - if self.seconds >= 0.0: - strval="%s:%02d:%02d:%05.2f" % (self.day, self.hour, - self.minute, self.second) - else: - strval="-%s:%02d:%02d:%05.2f" % (self.day, self.hour, - self.minute, self.second) - else: - if self.seconds >= 0.0: - strval="%02d:%02d:%05.2f" % (self.hour, self.minute, - self.second) - else: - strval="-%02d:%02d:%05.2f" % (self.hour, self.minute, - self.second) - return "" % (strval, id(self)) - - def __abs__(self): - if self.seconds < 0: - return -self - return self - - def __nonzero__(self): - return self.seconds != 0.0 - - def __add__(self, other): - if type(other) == types.InstanceType: - if isinstance(other,DateTime): - return other + self - elif isinstance(other,DateTimeDelta): - return DateTimeDelta(0.0,0.0,0.0,self.seconds + other.seconds) - - # What about __radd__ ? - -# Other DateTimeDelta constructors - -def TimeDelta(hour=0.0, minute=0.0, second=0.0): - return DateTimeDelta(0.0, hours, minutes, seconds) - -Time=TimeDelta - -def DateTimeDeltaFromSeconds(seconds): - return DateTimeDelta(0.0,0.0,0.0,seconds) - -def DateTimeDeltaFromDays(days): - return DateTimeDelta(days) - -### Types - -DateTimeType = DateTime -DateTimeDeltaType = DateTimeDelta - -### Functions - -def cmp(a,b,acc): - - if isinstance(a,DateTime) and isinstance(b,DateTime): - diff = a.absdays - b.absdays - if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc): - return 0 - elif diff < 0: - return 1 - else: - return -1 - - elif isinstance(a,DateTimeDelta) and isinstance(b,DateTimeDelta): - diff = a.days - b.days - if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc): - return 0 - elif diff < 0: - return 1 - else: - return -1 - - else: - raise TypeError,"objects must be DateTime[Delta] instances"