Commit e36a38c9 authored by Shane Hathaway's avatar Shane Hathaway

Added implementations of __gt__, __le__, etc. to DateTime. With these,

sorting a list of 30000 DateTimes is *eighteen times faster* when used
with Python 2.1 and 2.2.  (But this may actually just restore the former
performace of DateTime on Python 1.5.2.)  Also added tests.  This should
help ZCatalog.
parent 2285478d
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
############################################################################## ##############################################################################
"""Encapsulation of date/time values""" """Encapsulation of date/time values"""
__version__='$Revision: 1.71 $'[11:-2] __version__='$Revision: 1.72 $'[11:-2]
import re,sys, os, math, DateTimeZone import re,sys, os, math, DateTimeZone
...@@ -1133,6 +1133,7 @@ class DateTime: ...@@ -1133,6 +1133,7 @@ class DateTime:
the current object\'s day, in the object\'s timezone context""" the current object\'s day, in the object\'s timezone context"""
return self.__class__(self._year,self._month,self._day, return self.__class__(self._year,self._month,self._day,
23,59,59,self._tz) 23,59,59,self._tz)
def greaterThan(self,t): def greaterThan(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
OR a floating point number such as that which is returned OR a floating point number such as that which is returned
...@@ -1142,8 +1143,15 @@ class DateTime: ...@@ -1142,8 +1143,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() > t.millis()) # Optimized for sorting speed
except: return (self._t > t) try:
return (self._millis > t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t > t)
__gt__ = greaterThan
def greaterThanEqualTo(self,t): def greaterThanEqualTo(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
...@@ -1154,8 +1162,15 @@ class DateTime: ...@@ -1154,8 +1162,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() >= t.millis()) # Optimized for sorting speed
except: return (self._t >= t) try:
return (self._millis >= t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t >= t)
__ge__ = greaterThanEqualTo
def equalTo(self,t): def equalTo(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
...@@ -1166,8 +1181,15 @@ class DateTime: ...@@ -1166,8 +1181,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() == t.millis()) # Optimized for sorting speed
except: return (self._t == t) try:
return (self._millis == t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t == t)
__eq__ = equalTo
def notEqualTo(self,t): def notEqualTo(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
...@@ -1178,8 +1200,15 @@ class DateTime: ...@@ -1178,8 +1200,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() != t.millis()) # Optimized for sorting speed
except: return (self._t != t) try:
return (self._millis != t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t != t)
__ne__ = notEqualTo
def lessThan(self,t): def lessThan(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
...@@ -1190,8 +1219,15 @@ class DateTime: ...@@ -1190,8 +1219,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() < t.millis()) # Optimized for sorting speed
except: return (self._t < t) try:
return (self._millis < t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t < t)
__lt__ = lessThan
def lessThanEqualTo(self,t): def lessThanEqualTo(self,t):
"""Compare this DateTime object to another DateTime object """Compare this DateTime object to another DateTime object
...@@ -1202,8 +1238,15 @@ class DateTime: ...@@ -1202,8 +1238,15 @@ class DateTime:
Revised to give more correct results through comparison of Revised to give more correct results through comparison of
long integer milliseconds. long integer milliseconds.
""" """
try: return (self.millis() <= t.millis()) # Optimized for sorting speed
except: return (self._t <= t) try:
return (self._millis <= t._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return (self._t <= t)
__le__ = lessThanEqualTo
def isLeapYear(self): def isLeapYear(self):
"""Return true if the current year (in the context of the object\'s """Return true if the current year (in the context of the object\'s
...@@ -1314,11 +1357,15 @@ class DateTime: ...@@ -1314,11 +1357,15 @@ class DateTime:
def millis(self): def millis(self):
"""Return the millisecond since the epoch in GMT.""" """Return the millisecond since the epoch in GMT."""
try: millis = self._millis try:
except: return self._millis
# Upgrade a previously pickled DateTime object. except AttributeError:
millis = long(math.floor(self._t * 1000.0)) return self._upgrade_old()
self._millis = millis
def _upgrade_old(self):
"""Upgrades a previously pickled DateTime object."""
millis = long(math.floor(self._t * 1000.0))
self._millis = millis
return millis return millis
def strftime(self, format): def strftime(self, format):
...@@ -1514,8 +1561,13 @@ class DateTime: ...@@ -1514,8 +1561,13 @@ class DateTime:
You should use the methods lessThan, greaterThan, You should use the methods lessThan, greaterThan,
lessThanEqualTo, greaterThanEqualTo, equalTo and lessThanEqualTo, greaterThanEqualTo, equalTo and
notEqualTo to avoid potential problems later!!""" notEqualTo to avoid potential problems later!!"""
try: return cmp(self.millis(), obj.millis()) # Optimized for sorting speed.
except AttributeError: return cmp(self._t,obj) try:
return cmp(self._millis, obj._millis)
except AttributeError:
try: self._millis
except AttributeError: self._upgrade_old()
return cmp(self._t,obj)
def __hash__(self): def __hash__(self):
"""Compute a hash value for a DateTime""" """Compute a hash value for a DateTime"""
......
...@@ -133,6 +133,38 @@ class DateTimeTests (unittest.TestCase): ...@@ -133,6 +133,38 @@ class DateTimeTests (unittest.TestCase):
dt1 = DateTime('1997/3/9 1:45pm GMT+8') dt1 = DateTime('1997/3/9 1:45pm GMT+8')
assert dt1 - dt == 1.0, (dt, dt1) assert dt1 - dt == 1.0, (dt, dt1)
def testCompareMethods(self):
'''Compare two dates using several methods'''
dt = DateTime('1997/1/1')
dt1 = DateTime('1997/2/2')
self.failUnless(dt1.greaterThan(dt))
self.failUnless(dt1.greaterThanEqualTo(dt))
self.failUnless(dt.lessThan(dt1))
self.failUnless(dt.lessThanEqualTo(dt1))
self.failUnless(dt.notEqualTo(dt1))
self.failUnless(not dt.equalTo(dt1))
def testCompareOperations(self, dt=None, dt1=None):
"""Compare two dates using several operations"""
if dt is None:
dt = DateTime('1997/1/1')
if dt1 is None:
dt1 = DateTime('1997/2/2')
self.failUnless(dt1 > dt)
self.failUnless(dt1 >= dt)
self.failUnless(dt < dt1)
self.failUnless(dt <= dt1)
self.failUnless(dt != dt1)
self.failUnless(not (dt == dt1))
def testUpgradeOldInstances(self):
"""Compare dates that don't have the _millis attribute yet."""
dt = DateTime('1997/1/1')
dt1 = DateTime('1997/2/2')
del dt._millis
del dt1._millis
self.testCompareOperations(dt, dt1)
def testTZ2(self): def testTZ2(self):
'''Time zone manipulation test 2''' '''Time zone manipulation test 2'''
dt = DateTime() dt = DateTime()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment