embedded/mx/DateTime/mxDateTime_python.py
changeset 1808 aa09e20dd8c0
parent 1693 49075f57cf2c
parent 1807 6d541c610165
child 1810 e95e876be17c
equal deleted inserted replaced
1693:49075f57cf2c 1808:aa09e20dd8c0
     1 """
       
     2     Python implementation courtesy of Drew Csillag (StarMedia Network, Inc.)
       
     3 
       
     4     This version has been somewhat modified by MAL. It is still fairly
       
     5     rough though and not necessarily high performance... 
       
     6 
       
     7     XXX Still needs testing and checkup !!!
       
     8 
       
     9     WARNING: Using this file is only recommended if you really must
       
    10     use it for some reason. It is not being actively maintained !
       
    11 
       
    12 """
       
    13 
       
    14 __version__ = '1.2.0 [Python]'
       
    15 
       
    16 import time,types,exceptions,math
       
    17 
       
    18 ### Errors
       
    19 
       
    20 class Error(exceptions.StandardError):
       
    21     pass
       
    22 
       
    23 class RangeError(Error):
       
    24     pass
       
    25 
       
    26 ### Constants (internal use only)
       
    27 
       
    28 month_offset=(
       
    29     (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365),
       
    30     (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366),
       
    31     )
       
    32 
       
    33 days_in_month=(
       
    34     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
       
    35     (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
       
    36     )
       
    37 
       
    38 ### Helpers
       
    39 
       
    40 def _IS_LEAPYEAR(d):
       
    41     return ((d.year % 4 == 0)
       
    42             and (
       
    43                 (d.year % 100 != 0)
       
    44                 or (d.year % 400 == 0)
       
    45                 )
       
    46             )
       
    47 
       
    48 def _YEAROFFSET(d):
       
    49     return (
       
    50         (d.year - 1) * 365
       
    51         + (d.year - 1) / 4
       
    52         - (d.year - 1) / 100
       
    53         + (d.year - 1) / 400
       
    54         )
       
    55 
       
    56 class _EmptyClass:
       
    57     pass
       
    58 
       
    59 def createEmptyObject(Class,
       
    60                       _EmptyClass=_EmptyClass):
       
    61 
       
    62     o = _EmptyClass()
       
    63     o.__class__ = Class
       
    64     return o
       
    65 
       
    66 ### DateTime class
       
    67 
       
    68 class DateTime:
       
    69 
       
    70     def __init__(self, year, month=1, day=1, hour=0, minute=0, second=0.0):
       
    71 
       
    72         second=1.0 * second
       
    73         if month <= 0:
       
    74             raise RangeError, "year out of range (>0)"
       
    75 
       
    76         #calculate absolute date
       
    77         leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0))
       
    78 
       
    79         #Negative values indicate days relative to the years end
       
    80         if month < 0:
       
    81             month = month + 13 
       
    82 
       
    83         if not (month >= 1 and month <= 12):
       
    84             raise RangeError, "month out of range (1-12)"
       
    85 
       
    86         #Negative values indicate days relative to the months end
       
    87         if (day < 0):
       
    88             day = day + days_in_month[leap][month - 1] + 1;
       
    89 
       
    90         if not (day >= 1 and day <= days_in_month[leap][month - 1]):
       
    91             raise RangeError, "day out of range"
       
    92 
       
    93         year = year - 1
       
    94         yearoffset = year * 365 + year / 4 - year / 100 + year / 400
       
    95         year = year + 1
       
    96         absdate = day + month_offset[leap][month - 1] + yearoffset;
       
    97 
       
    98         self.absdate = absdate
       
    99         self.year = year
       
   100         self.month = month
       
   101         self.day = day
       
   102         self.day_of_week = (absdate - 1) % 7
       
   103         self.day_of_year = absdate - yearoffset
       
   104         self.days_in_month = days_in_month[leap][month - 1]
       
   105         comdate = absdate - 693594
       
   106 
       
   107         if not (hour >=0 and hour <= 23):
       
   108             raise RangeError, "hour out of range (0-23)"
       
   109         if not (minute >= 0 and minute <= 59):
       
   110             raise RangeError, "minute out of range (0-59)"
       
   111         if not (second >= 0.0 and
       
   112                 (second < 60.0 or 
       
   113                  (hour == 23 and minute == 59 and second < 61.0))):
       
   114             raise RangeError, "second out of range (0.0 - <60.0; <61.0 for 23:59)"
       
   115 
       
   116         self.abstime = (hour * 3600 + minute * 60) + second
       
   117         self.hour = hour
       
   118         self.minute = minute
       
   119         self.second = second
       
   120         self.dst = -1
       
   121         self.tz = "???"
       
   122         self.is_leapyear = leap
       
   123         self.yearoffset = yearoffset
       
   124         self.iso_week = (self.year, self.day, self.day_of_week)
       
   125 
       
   126         if comdate < 0.0:
       
   127             comdate = comdate - self.abstime / 86400.0
       
   128         else:
       
   129             comdate = comdate + self.abstime / 86400.0
       
   130 
       
   131         self.comdate = comdate
       
   132 
       
   133     def COMDate(self):
       
   134         return self.comdate
       
   135     
       
   136     def __str__(self):
       
   137         return "%04d-%02d-%02d %02d:%02d:%05.2f" % (
       
   138             self.year, self.month, self.day, self.hour, self.minute,
       
   139             self.second)
       
   140     
       
   141     def __getattr__(self, attr):
       
   142         if attr == 'mjd':
       
   143             return (self - mjd0).days
       
   144         elif attr == 'jdn':
       
   145             return (self - jdn0).days
       
   146         elif attr == 'tjd':
       
   147             return (self - jdn0).days % 10000
       
   148         elif attr == 'tjd_myriad':
       
   149             return int((self - jdn0).days) / 10000 + 240
       
   150         elif attr == 'absdays':
       
   151             return self.absdate - 1 + self.abstime / 86400.0
       
   152         else:
       
   153             try:
       
   154                 return self.__dict__[attr]
       
   155             except:
       
   156                 raise AttributeError, attr
       
   157 
       
   158     def __mul__(self, other):
       
   159         raise TypeError, "bad operand type(s) for *"
       
   160 
       
   161     def __div__(self, other):
       
   162         raise TypeError, "bad operand type(s) for /"
       
   163     
       
   164     def strftime(self, format_string="%c"):
       
   165         "localtime([seconds]) -> (tm_year,tm_mon,tm_day,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)"
       
   166         # The map prevents a deprecation warning on Python 2.5.1 (Mac)
       
   167         # DeprecationWarning: integer argument expected, got float
       
   168         items = [int(item) for item in self.tuple()]
       
   169         return time.strftime(format_string, items)
       
   170 
       
   171     # Alias
       
   172     Format = strftime
       
   173     
       
   174     def tuple(self):
       
   175         return (self.year, self.month, self.day, self.hour, self.minute,
       
   176                 self.second, self.day_of_week, self.day_of_year, -1)
       
   177         #return time.localtime(self.ticks())
       
   178 
       
   179     def absvalues(self):
       
   180         return self.absdate, self.abstime
       
   181     
       
   182     def __float__(self):
       
   183         return self.ticks()
       
   184 
       
   185     def __int__(self):
       
   186         return int(self.ticks)
       
   187     
       
   188     def ticks(self, offset=0.0, dst=-1):
       
   189         tticks=time.mktime(self.year, self.month, self.day, self.hour,
       
   190                            self.minute, self.second, self.day_of_week, 0, dst)
       
   191         if tticks == -1:
       
   192             raise OverflowError, "cannot convert value to a time value"
       
   193         ticks = (1.0*tticks) + (self.abstime - int(self.abstime)) - offset
       
   194         return ticks
       
   195 
       
   196     def gmticks(self, offset=0.0):
       
   197         from mx.DateTime import tz_offset
       
   198         return (self-tz_offset(self)).ticks()
       
   199 
       
   200     def gmtoffset(self):
       
   201         gmtime = DateTime(*time.gmtime()[:6])
       
   202         return - (now() - gmtime)
       
   203     
       
   204     def __repr__(self):
       
   205         return "<DateTime object for '%d-%02d-%02d %02d:%02d:%05.2f' at %x>"% (
       
   206             self.year, self.month, self.day, self.hour, self.minute,
       
   207             self.second, id(self))
       
   208 
       
   209     def __cmp__(self, other,
       
   210                 cmp=cmp):
       
   211 
       
   212         if isinstance(other,DateTime):
       
   213             cmpdate = cmp(self.absdate,other.absdate)
       
   214             if cmpdate == 0:
       
   215                 return cmp(self.abstime,other.abstime)
       
   216             else:
       
   217                 return cmpdate
       
   218         elif type(other) == types.NoneType:
       
   219             return -1
       
   220         elif type(other) == types.StringType:
       
   221             return -1
       
   222         elif type(other) in (types.FloatType, types.LongType, types.IntType):
       
   223             return 1
       
   224         return -1
       
   225 
       
   226     def __hash__(self):
       
   227         return hash(self.tuple())
       
   228     
       
   229     def __add__(self, other):
       
   230         abstime=self.abstime
       
   231         absdate=self.absdate
       
   232 
       
   233         didadd=0
       
   234         
       
   235         if type(other) == types.InstanceType:
       
   236             if other.__class__ == DateTimeDelta:
       
   237                 abstime = abstime + other.seconds
       
   238                 didadd=1
       
   239             elif other.__class__ == DateTime:
       
   240                 raise TypeError, "DateTime + DateTime is not supported"
       
   241             else:
       
   242                 return other.__class__.__radd__(other, self)
       
   243             
       
   244         elif type(other) == types.IntType or type(other) == types.FloatType:
       
   245             abstime = abstime + other * 86400.0
       
   246             didadd=1
       
   247 
       
   248         if not didadd:
       
   249             raise TypeError, "cannot add these two types"
       
   250 
       
   251         if abstime >= 86400.0:
       
   252             days = abstime / 86400.0
       
   253             absdate = absdate + days
       
   254             abstime = abstime - (86400.0 * int(days))
       
   255             #print "absdate, abstime = ", absdate, abstime
       
   256         elif abstime < 0.0:
       
   257             days = int(((-abstime - 1) / 86400.0)) + 1
       
   258             #days = int(-abstime / 86400.0)
       
   259             absdate = absdate - days
       
   260             abstime = abstime + 86400.0 * int(days)
       
   261 
       
   262         if absdate < 1:
       
   263             raise RangeError, "underflow while adding"
       
   264 
       
   265         return DateTimeFromAbsDateTime(absdate, abstime)
       
   266 
       
   267     def __radd__(self, other):
       
   268         return DateTime.__add__(other, self)
       
   269     
       
   270     def __sub__(self, other):
       
   271         abstime=self.abstime
       
   272         absdate=self.absdate
       
   273 
       
   274         didsub=0
       
   275         if type(other) == types.InstanceType:
       
   276             if other.__class__ == DateTimeDelta:
       
   277                 abstime = abstime - other.seconds
       
   278                 didsub = 1
       
   279             elif other.__class__ == DateTime:
       
   280                 absdate = absdate - other.absdate
       
   281                 abstime = abstime - other.abstime
       
   282                 return DateTimeDelta(absdate,0.0,0.0,abstime)
       
   283             else:
       
   284                 return other.__rsub__(self)
       
   285 
       
   286         elif type(other) == types.IntType or type(other) == types.FloatType:
       
   287             abstime = abstime - other * 86400.0;
       
   288             didsub=1
       
   289 
       
   290         if not didsub:
       
   291             raise TypeError, "cannot subtract these two types"
       
   292 
       
   293         if abstime >= 86400.0:
       
   294             days = abstime / 86400.0
       
   295             absdate = absdate + days
       
   296             abstime = abstime - (86400.0 * days)
       
   297             #print "absdate, abstime = ", absdate, abstime
       
   298         elif abstime < 0.0:
       
   299             #print "abstime < 0"
       
   300             days = int( ((-abstime - 1) / 86400.0) + 1)
       
   301             #days = -abstime / 86400.0
       
   302             absdate = absdate - int(days)
       
   303             abstime = (1.0*abstime) + (86400.0 * days)
       
   304             #print "absdate, abstime", absdate, abstime
       
   305         if absdate < 1:
       
   306             raise RangeError, "underflow while adding"
       
   307 
       
   308         return DateTimeFromAbsDateTime(absdate, abstime)
       
   309 
       
   310 # Constants
       
   311 mjd0 = DateTime(1858, 11, 17)
       
   312 jdn0 = DateTime(-4713, 1, 1, 12, 0, 0.0)
       
   313 
       
   314 # Other DateTime constructors
       
   315 
       
   316 def DateTimeFromCOMDate(comdate):
       
   317 
       
   318     absdate = int(comdate)
       
   319     abstime = (comdate - float(absdate)) * 86400.0
       
   320     if abstime < 0.0:
       
   321         abstime = -abstime
       
   322     absdate = absdate + 693594;
       
   323     dt = DateTimeFromAbsDateTime(absdate, abstime)
       
   324     dt.comdate = comdate
       
   325     return dt
       
   326     
       
   327 def DateTimeFromAbsDateTime(absdate, abstime):
       
   328 
       
   329     # Create the object without calling its default constructor
       
   330     dt = createEmptyObject(DateTime)
       
   331 
       
   332     # Init. the object
       
   333     abstime=1.0 * abstime
       
   334     if abstime < 0 and abstime > -0.001: abstime = 0.0
       
   335     if not (absdate > 0):
       
   336         raise RangeError, "absdate out of range (>0)"
       
   337     if not (abstime >= 0.0 and abstime <= 86400.0):
       
   338         raise RangeError, "abstime out of range (0.0 - 86400.0) <%s>" % abstime
       
   339 
       
   340     dt.absdate=absdate
       
   341     dt.abstime=abstime
       
   342 
       
   343     #calculate com date
       
   344     comdate = 1.0 * (dt.absdate - 693594)
       
   345     if comdate < 0.0:
       
   346         comdate = comdate - dt.abstime / 86400.0
       
   347     else:
       
   348         comdate = comdate + dt.abstime / 86400.0
       
   349     dt.comdate = comdate
       
   350 
       
   351     #calculate the date
       
   352     #print "absdate=", absdate
       
   353     year = int((1.0 * absdate) / 365.2425)
       
   354 
       
   355     #newApproximation:
       
   356     while 1:
       
   357         #print "year=", year
       
   358         yearoffset = year * 365 + year / 4 - year / 100 + year / 400
       
   359         #print "yearoffset=", yearoffset
       
   360         #print "absdate=", absdate
       
   361         if yearoffset >= absdate:
       
   362             year = year - 1
       
   363             #print "year = ", year
       
   364             continue #goto newApproximation
       
   365 
       
   366         year = year + 1
       
   367         leap = (year % 4 == 0) and ((year % 100 != 0) or (year % 400 == 0))
       
   368         dayoffset = absdate - yearoffset
       
   369         #print "dayoffset=", dayoffset
       
   370         if dayoffset > 365 and leap == 0:
       
   371             #print "dayoffset=", dayoffset
       
   372             continue #goto newApproximation
       
   373 
       
   374         monthoffset = month_offset[leap]
       
   375         for month in range(1, 13):
       
   376             if monthoffset[month] >= dayoffset:
       
   377                 break
       
   378         dt.year = year
       
   379         dt.month = month
       
   380         dt.day = dayoffset - month_offset[leap][month-1]
       
   381         dt.day_of_week = (dt.absdate - 1) % 7
       
   382         dt.day_of_year = dayoffset
       
   383         break
       
   384     
       
   385     #calculate the time
       
   386     inttime = int(abstime)
       
   387     hour = inttime / 3600
       
   388     minute = (inttime % 3600) / 60
       
   389     second = abstime - 1.0 * (hour*3600 + minute*60)
       
   390     dt.hour = hour;
       
   391     dt.minute = minute;
       
   392     dt.second = second;
       
   393     dt.days_in_month = days_in_month[leap][month - 1]
       
   394     dt.dst = -1
       
   395     dt.tz = "???"
       
   396     dt.is_leapyear = leap
       
   397     dt.yearoffset = yearoffset
       
   398     return dt
       
   399 
       
   400 def now(
       
   401         time=time.time,float=float,localtime=time.localtime,
       
   402         round=round,int=int,DateTime=DateTime,floor=math.floor):
       
   403     ticks = time()
       
   404     Y,M,D,h,m,s = localtime(ticks)[:6]
       
   405     s = s + (ticks - floor(ticks))
       
   406     return DateTime(Y,M,D,h,m,s)
       
   407 
       
   408 def utc(
       
   409         time=time.time,float=float,gmtime=time.gmtime,
       
   410         round=round,int=int,DateTime=DateTime,floor=math.floor):
       
   411 
       
   412     ticks = time()
       
   413     Y,M,D,h,m,s = gmtime(ticks)[:6]
       
   414     s = s + (ticks - floor(ticks))
       
   415     return DateTime(Y,M,D,h,m,s)
       
   416 
       
   417 # Aliases
       
   418 Date = Timestamp = DateTime
       
   419 
       
   420 # XXX Calendars are not supported:
       
   421 def notSupported(*args,**kws):
       
   422     raise Error,'calendars are not supported by the Python version of mxDateTime'
       
   423 JulianDateTime = notSupported
       
   424 
       
   425 ### DateTimeDelta class
       
   426                
       
   427 class DateTimeDelta:
       
   428 
       
   429     def __init__(self, days=0, hours=0, minutes=0, seconds=0):
       
   430 
       
   431         seconds = seconds + (days * 86400.0 + hours * 3600.0 + minutes * 60.0)
       
   432         self.seconds = seconds
       
   433         if seconds < 0.0:
       
   434             seconds = -seconds
       
   435         day = long(seconds / 86400.0)
       
   436         seconds = seconds - (86400.0 * day)
       
   437         wholeseconds = int(seconds)
       
   438         hour = wholeseconds / 3600
       
   439         minute = (wholeseconds % 3600) / 60
       
   440         second = seconds - (hour * 3600.0 + minute * 60.0)
       
   441         self.day = day
       
   442         self.hour = hour
       
   443         self.minute = minute
       
   444         self.second = second
       
   445         seconds=self.seconds
       
   446         self.minutes = seconds / 60.0
       
   447         self.hours = seconds / 3600.0
       
   448         self.days = seconds / 86400.0
       
   449 
       
   450     def __str__(self):
       
   451         if self.day != 0:
       
   452             if self.seconds >= 0.0:
       
   453                 r="%s:%02d:%02d:%05.2f" % (
       
   454                     self.day, self.hour, self.minute, self.second)
       
   455             else:
       
   456                 r="-%s:%02d:%02d:%05.2f" % (
       
   457                     self.day, self.hour, self.minute, self.second)
       
   458         else:
       
   459             if self.seconds >= 0.0:
       
   460                 r="%02d:%02d:%05.2f" % (self.hour, self.minute, self.second)
       
   461             else:
       
   462                 r="-%02d:%02d:%05.2f" % (self.hour, self.minute, self.second)
       
   463         return r
       
   464             
       
   465     def absvalues(self):
       
   466         days=self.seconds / 86400
       
   467         seconds=self.seconds - (days * 86400.0)
       
   468         return days, seconds
       
   469 
       
   470     def tuple(self):
       
   471         return (self.day, self.hour, self.minute, self.second)
       
   472 
       
   473     def strftime(self, format_string):
       
   474         raise NotImplementedError
       
   475     
       
   476     def __int__(self):
       
   477         return int(self.seconds)
       
   478 
       
   479     def __float__(self):
       
   480         return self.seconds
       
   481     
       
   482     def __cmp__(self, other, accuracy=0.0):
       
   483         if (type(other) == types.InstanceType
       
   484             and other.__class__ == DateTimeDelta):
       
   485 
       
   486             diff=self.seconds - other.seconds
       
   487             if abs(diff) > accuracy:
       
   488                 if diff > 0: return 1
       
   489                 return -1
       
   490             
       
   491         elif type(other) == types.FloatType:
       
   492             diff=self.seconds - other
       
   493             if abs(diff) > accuracy:
       
   494                 if diff > 0: return 1
       
   495                 return -1
       
   496             
       
   497         elif type(other) == types.IntType:
       
   498             diff=self.seconds - other
       
   499             if abs(diff) > accuracy:
       
   500                 if diff > 0: return 1
       
   501                 return -1
       
   502             
       
   503         return 0
       
   504     
       
   505     def __getattr__(self, attr):
       
   506         seconds=self.__dict__['seconds']
       
   507         if attr in ('hour', 'minute', 'second', 'day'):
       
   508             if seconds >= 0.0:
       
   509                 return self.__dict__[attr]
       
   510             else:
       
   511                 return -self.__dict__[attr]
       
   512         else:
       
   513             try:
       
   514                 return self.__dict__[attr]
       
   515             except:
       
   516                 raise AttributeError, attr
       
   517 
       
   518     def __div__(self, other):
       
   519         if type(other) in (types.IntType, types.FloatType):
       
   520             return DateTimeDelta(0.0,0.0,0.0,self.seconds / other)
       
   521         elif (type(other) == types.InstanceType
       
   522               and isinstance(other,DateTimeDelta)):
       
   523             return DateTimeDelta(0.0,0.0,0.0,self.seconds / other.seconds)
       
   524         raise TypeError, "bad operand types for /"
       
   525     
       
   526     def __mul__(self, other):
       
   527         if type(other) == types.IntType or type(other) == types.FloatType:
       
   528             return DateTimeDelta(0.0,0.0,0.0,self.seconds * other)
       
   529         else:
       
   530             #print "type", type(other)
       
   531             raise TypeError, "cannot multiply these two types"
       
   532 
       
   533     def __rmul__(self, other):
       
   534         return self.__mul__(other)
       
   535     
       
   536     def __neg__(self):
       
   537         return DateTimeDelta(0.0,0.0,0.0,-self.seconds)
       
   538         
       
   539     def __repr__(self):
       
   540         if self.day != 0:
       
   541             if self.seconds >= 0.0:
       
   542                 strval="%s:%02d:%02d:%05.2f" % (self.day, self.hour,
       
   543                                                  self.minute, self.second)
       
   544             else:
       
   545                 strval="-%s:%02d:%02d:%05.2f" % (self.day, self.hour,
       
   546                                                   self.minute, self.second)
       
   547         else:
       
   548             if self.seconds >= 0.0:
       
   549                 strval="%02d:%02d:%05.2f" % (self.hour, self.minute,
       
   550                                             self.second)
       
   551             else:
       
   552                 strval="-%02d:%02d:%05.2f" % (self.hour, self.minute,
       
   553                                              self.second)
       
   554         return "<DateTimeDelta object for '%s' at %x>" % (strval, id(self))
       
   555     
       
   556     def __abs__(self):
       
   557         if self.seconds < 0:
       
   558             return -self
       
   559         return self
       
   560 
       
   561     def __nonzero__(self):
       
   562         return self.seconds != 0.0
       
   563     
       
   564     def __add__(self, other):
       
   565         if type(other) == types.InstanceType:
       
   566             if isinstance(other,DateTime):
       
   567                 return other + self
       
   568             elif isinstance(other,DateTimeDelta):
       
   569                 return DateTimeDelta(0.0,0.0,0.0,self.seconds + other.seconds)
       
   570 
       
   571     # What about __radd__ ?
       
   572         
       
   573 # Other DateTimeDelta constructors
       
   574 
       
   575 def TimeDelta(hour=0.0, minute=0.0, second=0.0):
       
   576     return DateTimeDelta(0.0, hours, minutes, seconds)
       
   577 
       
   578 Time=TimeDelta
       
   579 
       
   580 def DateTimeDeltaFromSeconds(seconds):
       
   581     return DateTimeDelta(0.0,0.0,0.0,seconds)
       
   582 
       
   583 def DateTimeDeltaFromDays(days):
       
   584     return DateTimeDelta(days)
       
   585 
       
   586 ### Types
       
   587 
       
   588 DateTimeType = DateTime
       
   589 DateTimeDeltaType = DateTimeDelta
       
   590 
       
   591 ### Functions
       
   592 
       
   593 def cmp(a,b,acc):
       
   594 
       
   595     if isinstance(a,DateTime) and isinstance(b,DateTime):
       
   596         diff = a.absdays - b.absdays
       
   597         if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc):
       
   598             return 0
       
   599         elif diff < 0:
       
   600             return 1
       
   601         else:
       
   602             return -1
       
   603 
       
   604     elif isinstance(a,DateTimeDelta) and isinstance(b,DateTimeDelta):
       
   605         diff = a.days - b.days
       
   606         if (diff >= 0 and diff <= acc) or (diff < 0 and -diff <= acc):
       
   607             return 0
       
   608         elif diff < 0:
       
   609             return 1
       
   610         else:
       
   611             return -1
       
   612 
       
   613     else:
       
   614         raise TypeError,"objects must be DateTime[Delta] instances"