[Zope3-checkins] CVS: Zope3/lib/python/datetime - _datetime.py:1.7 test_datetime.py:1.7 __init__.py:1.3
Viktorija Zaksiene
ryzaja@codeworks.lt
Mon, 2 Dec 2002 04:56:12 -0500
Update of /cvs-repository/Zope3/lib/python/datetime
In directory cvs.zope.org:/tmp/cvs-serv6358/datetime
Modified Files:
_datetime.py test_datetime.py __init__.py
Log Message:
Synchronized with Python 2.3 datetime.
=== Zope3/lib/python/datetime/_datetime.py 1.6 => 1.7 ===
--- Zope3/lib/python/datetime/_datetime.py:1.6 Thu Nov 21 05:42:35 2002
+++ Zope3/lib/python/datetime/_datetime.py Mon Dec 2 04:56:11 2002
@@ -693,6 +693,310 @@
date.resolution = timedelta(days=1)
+class time(object):
+ """Concrete time type.
+
+ Constructors:
+
+ __init__()
+
+ Operators:
+
+ __repr__, __str__
+ __cmp__, __hash__
+
+ Methods:
+
+ strftime()
+ isoformat()
+
+ Properties (readonly):
+ hour, minute, second, microsecond
+ """
+
+ def __init__(self, hour, minute, second=0, microsecond=0):
+ """Constructor.
+
+ Arguments:
+
+ hour, minute (required)
+ second, microsecond (default to zero)
+ """
+ if not 0 <= hour <= 23:
+ raise ValueError('hour must be in 0..23', hour)
+ if not 0 <= minute <= 59:
+ raise ValueError('minute must be in 0..59', minute)
+ if not 0 <= second <= 59:
+ raise ValueError('second must be in 0..59', second)
+ if not 0 <= microsecond <= 999999:
+ raise ValueError('microsecond must be in 0..999999', microsecond)
+ self.__hour = hour
+ self.__minute = minute
+ self.__second = second
+ self.__microsecond = microsecond
+
+ # Read-only field accessors
+ hour = property(lambda self: self.__hour, doc="hour (0-23)")
+ minute = property(lambda self: self.__minute, doc="minute (0-59)")
+ second = property(lambda self: self.__second, doc="second (0-59)")
+ microsecond = property(lambda self: self.__microsecond,
+ doc="microsecond (0-999999)")
+
+ # Standard conversions, __cmp__, __hash__ (and helpers)
+
+ def __cmp__(self, other):
+ """Three-way comparison."""
+ if isinstance(other, time):
+ return cmp((self.__hour, self.__minute, self.__second,
+ self.__microsecond),
+ (other.__hour, other.__minute, other.__second,
+ other.__microsecond))
+ raise TypeError, ("can't compare time to %s instance" %
+ type(other).__name__)
+
+ def __hash__(self):
+ """Hash."""
+ return hash((self.__hour, self.__minute, self.__second,
+ self.__microsecond))
+
+ # Conversions to string
+
+ def __repr__(self):
+ """Convert to formal string, for repr()."""
+ if self.__microsecond != 0:
+ s = ", %d, %d" % (self.__second, self.__microsecond)
+ elif self.__second != 0:
+ s = ", %d" % self.__second
+ else:
+ s = ""
+ return "%s(%d, %d%s)" % (self.__class__.__name__,
+ self.__hour, self.__minute, s)
+
+ def __str__(self):
+ """Convert to pretty string, for str()."""
+ pretty = "%d:%02d:%02d.%06d" % (
+ self.__hour, self.__minute, self.__second,
+ self.__microsecond)
+ # trim microseconds: hh:mm:ss.xxx000 -> hh:mm:ss.xxx
+ while pretty.endswith('0'):
+ pretty = pretty[:-1]
+ # trim microseconds: hh:mm:ss.000000 -> hh:mm:ss
+ if pretty.endswith('.'):
+ pretty = pretty[:-1]
+ # trim seconds: hh:mm:00 -> hh:mm
+ if pretty.endswith(':00'):
+ pretty = pretty[:-3]
+ return pretty
+
+ def isoformat(self):
+ """Return the time formatted according to ISO.
+
+ This is 'HH:MM:SS.mmmmmm'.
+ """
+ return "%02d:%02d:%02d.%06d" % (
+ self.__hour, self.__minute, self.__second,
+ self.__microsecond)
+
+ def strftime(self, fmt):
+ """Format using strftime(). The date part of the timestamp passed
+ to underlying strftime should not be used.
+ """
+ return _time.strftime(fmt, (0, 0, 0, self.__hour, self.__minute,
+ self.__second, 0, 0, -1))
+
+
+time.min = time(0, 0, 0)
+time.max = time(23, 59, 59, 999999)
+time.resolution = timedelta(microseconds=1)
+
+
+class timetz(time):
+ """Time with time zone.
+
+ Constructors:
+
+ __init__()
+
+ Operators:
+
+ __repr__, __str__
+ __cmp__, __hash__
+
+ Methods:
+
+ strftime()
+ isoformat()
+ utcoffset()
+ tzname()
+ dst()
+
+ Properties (readonly):
+ hour, minute, second, microsecond, tzinfo
+ """
+
+ def __init__(self, hour, minute, second=0, microsecond=0, tzinfo=None):
+ """Constructor.
+
+ Arguments:
+
+ hour, minute (required)
+ second, microsecond (default to zero)
+ tzinfo (default to None)
+ """
+ super(timetz, self).__init__(hour, minute, second, microsecond)
+ if tzinfo is not None:
+ # Better fail now than later
+ assert hasattr(tzinfo, 'utcoffset')
+ assert hasattr(tzinfo, 'dst')
+ assert hasattr(tzinfo, 'tzname')
+ self.__tzinfo = tzinfo
+
+ # Read-only field accessors
+ tzinfo = property(lambda self: self.__tzinfo, doc="timezone info object")
+
+ # Standard conversions, __cmp__, __hash__ (and helpers)
+
+ def __cmp__(self, other):
+ """Three-way comparison."""
+ if not isinstance(other, time):
+ raise TypeError("can't compare timetz to %s instance" %
+ type(other).__name__)
+ superself = super(timetz, self)
+ supercmp = superself.__cmp__
+ mytz = self.__tzinfo
+ ottz = None
+ if isinstance(other, timetz):
+ ottz = other.__tzinfo
+ if mytz is ottz:
+ return supercmp(other)
+ myoff = otoff = None
+ if mytz is not None:
+ myoff = mytz.utcoffset(self)
+ if ottz is not None:
+ otoff = ottz.utcoffset(other)
+ if myoff == otoff:
+ return supercmp(other)
+ if myoff is None or otoff is None:
+ raise ValueError, "cannot mix naive and timezone-aware time"
+ myhhmm = self.hour * 60 + self.minute - myoff
+ othhmm = other.hour * 60 + other.minute - otoff
+ return cmp((myhhmm, self.second, self.microsecond),
+ (othhmm, other.second, other.microsecond))
+
+ def __hash__(self):
+ """Hash."""
+ tz = self.__tzinfo
+ if tz == None:
+ return super(timetz, self).__hash__()
+ tzoff = tz.utcoffset(self)
+ if not tzoff: # zero or None!
+ return super(timetz, self).__hash__()
+ h, m = divmod(self.hour * 60 + self.minute - tzoff, 60)
+ # Unfortunately it is not possible to construct a new timetz object
+ # and use super().__hash__(), since hour may exceed the range of
+ # allowed values
+ return hash((h, m, self.second, self.microsecond))
+
+ # Conversion to string
+
+ def _tzstr(self, sep=":"):
+ """Return formatted timezone offset (+xx:xx) or None."""
+ if self.__tzinfo is not None:
+ off = self.__tzinfo.utcoffset(self)
+ if off is not None:
+ if off < 0:
+ sign = "-"
+ off = -off
+ else:
+ sign = "+"
+ hh, mm = divmod(off, 60)
+ return "%s%02d%s%02d" % (sign, hh, sep, mm)
+
+ def __repr__(self):
+ """Convert to formal string, for repr()."""
+ s = super(timetz, self).__repr__()
+ if self.__tzinfo is not None:
+ assert s[-1:] == ")"
+ s = s[:-1] + ", tzinfo=%r" % self.__tzinfo + ")"
+ return s
+
+ def __str__(self):
+ """Convert to pretty string, for str()."""
+ s = super(timetz, self).__str__()
+ tz = self._tzstr()
+ if tz: s = "%s %s" % (s, tz)
+ return s
+
+ def isoformat(self):
+ """Return the time formatted according to ISO.
+
+ This is 'HH:MM:SS.mmmmmm+zz:zz'.
+ """
+ s = super(timetz, self).isoformat()
+ tz = self._tzstr()
+ if tz: s += tz
+ return s
+
+ def strftime(self, fmt):
+ """Format using strftime(). The date part of the timestamp passed
+ to underlying strftime should not be used.
+
+ You can use %Z to refer to the timezone name and %z to refer to its
+ UTC offset (+zzzz).
+ """
+ tz = self._tzstr(sep="")
+ # FIXME: this will break %%z/%%Z!
+ if tz:
+ fmt = fmt.replace("%z", tz).replace("%Z", self.tzinfo.tzname(None))
+ else:
+ fmt = fmt.replace("%z", "").replace("%Z", "")
+ return super(timetz, self).strftime(fmt)
+
+ # Timezone functions
+
+ def utcoffset(self):
+ """Return the timezone offset in minutes east of UTC (negative west of
+ UTC)."""
+ tz = self.__tzinfo
+ if tz is None:
+ return None
+ else:
+ return tz.utcoffset(self)
+
+ def tzname(self):
+ """Return the timezone name.
+
+ Note that the name is 100% informational -- there's no requirement that
+ it mean anything in particular. For example, "GMT", "UTC", "-500",
+ "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
+ """
+ tz = self.__tzinfo
+ if tz is None:
+ return None
+ else:
+ return tz.tzname(self)
+
+ def dst(self):
+ """Return 0 if DST is not in effect, or the DST offset (in minutes
+ eastward) if DST is in effect.
+
+ This is purely informational; the DST offset has already been added to
+ the UTC offset returned by utcoffset() if applicable, so there's no
+ need to consult dst() unless you're interested in displaying the DST
+ info.
+ """
+ tz = self.__tzinfo
+ if tz is None:
+ return None
+ else:
+ return tz.dst(self)
+
+
+timetz.min = timetz(0, 0, 0)
+timetz.max = timetz(23, 59, 59, 999999)
+timetz.resolution = timedelta(microseconds=1)
+
+
class datetime(date):
"""Concrete date/time type, inheriting from date.
@@ -777,6 +1081,12 @@
return cls.utcfromtimestamp(t)
utcnow = classmethod(utcnow)
+ def combine(cls, date, time):
+ "Construct a datetime from a given date and a given time."
+ return cls(date.year, date.month, date.day,
+ time.hour, time.minute, time.second, time.microsecond)
+ combine = classmethod(combine)
+
# Conversions to string
def __repr__(self):
@@ -807,6 +1117,15 @@
self.__hour, self.__minute, self.__second,
self.weekday(), self._yday(), -1)
+ def date(self):
+ "Return the date part."
+ return date(self.__year, self.__month, self.__day)
+
+ def time(self):
+ "Return the time part."
+ return time(self.__hour, self.__minute, self.__second,
+ self.__microsecond)
+
def __cmp__(self, other):
"Three-way comparison."
if isinstance(other, datetime):
@@ -941,6 +1260,14 @@
return cls.fromtimestamp(t, tzinfo)
now = classmethod(now)
+ def combine(cls, date, time):
+ "Construct a datetime from a given date and a given time."
+ return cls(date.year, date.month, date.day,
+ time.hour, time.minute, time.second, time.microsecond,
+ getattr(time, 'tzinfo', None))
+ combine = classmethod(combine)
+
+
def utctimetuple(self):
"Return UTC time tuple compatible with time.gmtime()."
offset = self.utcoffset()
@@ -951,6 +1278,11 @@
self.microsecond)
dt = timedelta(minutes=offset)
return (ts - dt).timetuple()
+
+ def timetz(self):
+ "Return the time part."
+ return timetz(self.hour, self.minute, self.second, self.microsecond,
+ self.__tzinfo)
def isoformat(self, sep=' '):
s = super(datetimetz, self).isoformat(sep)
=== Zope3/lib/python/datetime/test_datetime.py 1.6 => 1.7 === (571/671 lines abridged)
--- Zope3/lib/python/datetime/test_datetime.py:1.6 Thu Nov 21 05:42:35 2002
+++ Zope3/lib/python/datetime/test_datetime.py Mon Dec 2 04:56:11 2002
@@ -6,98 +6,18 @@
import sys
import unittest
-from datetime import date, datetime, datetimetz, timedelta
-from datetime._datetime import MINYEAR, MAXYEAR
-
-
-class TestTimeDelta(unittest.TestCase):
-
- def test_timedelta(self):
- a = timedelta(7) # One week
- b = timedelta(0, 60) # One minute
- c = timedelta(0, 0, 1000) # One millisecond
- self.assertEqual(a+b+c, timedelta(7, 60, 1000))
- self.assertEqual(a-b, timedelta(6, 24*3600 - 60))
- self.assertEqual(-a, timedelta(-7))
- self.assertEqual(+a, timedelta(7))
- self.assertEqual(-b, timedelta(-1, 24*3600 - 60))
- self.assertEqual(-c, timedelta(-1, 24*3600 - 1, 999000))
- self.assertEqual(abs(a), a)
- self.assertEqual(abs(-a), a)
- self.assertEqual(timedelta(6, 24*3600), a)
- self.assertEqual(timedelta(0, 0, 60*1000000), b)
- self.assertEqual(a*10, timedelta(70))
- self.assertEqual(a*10, 10*a)
- self.assertEqual(a*10L, 10*a)
- self.assertEqual(b*10, timedelta(0, 600))
- self.assertEqual(10*b, timedelta(0, 600))
- self.assertEqual(b*10L, timedelta(0, 600))
- self.assertEqual(c*10, timedelta(0, 0, 10000))
- self.assertEqual(10*c, timedelta(0, 0, 10000))
- self.assertEqual(c*10L, timedelta(0, 0, 10000))
- self.assertEqual(a*-1, -a)
- self.assertEqual(b*-2, -b-b)
- self.assertEqual(c*-2, -c+-c)
- self.assertEqual(b*(60*24), (b*60)*24)
- self.assertEqual(b*(60*24), (60*b)*24)
- self.assertEqual(c*1000, timedelta(0, 1))
- self.assertEqual(1000*c, timedelta(0, 1))
- self.assertEqual(a//7, timedelta(1))
- self.assertEqual(b//10, timedelta(0, 6))
- self.assertEqual(c//1000, timedelta(0, 0, 1))
- self.assertEqual(a//10, timedelta(0, 7*24*360))
- self.assertEqual(a//3600000, timedelta(0, 0, 7*24*1000))
- # Add/sub ints, longs, floats should be illegal
- for i in 1, 1L, 1.0:
- self.assertRaises(TypeError, lambda: a+i)
[-=- -=- -=- 571 lines omitted -=- -=- -=-]
- def test_ctime(self):
- t = self.theclass(2002, 3, 2, 18, 3, 5, 123)
- self.assertEqual(t.ctime(), "Sat Mar 2 18:03:05 2002")
+ def test_combine(self):
+ d = date(2002, 3, 4)
+ t = time(18, 45, 3, 1234)
+ dt = datetime.combine(d, t)
+ self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234))
+
+ def test_extract(self):
+ dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
+ self.assertEqual(dt.date(), date(2002, 3, 4))
+ self.assertEqual(dt.time(), time(18, 45, 3, 1234))
class FixedOffset(object):
@@ -582,13 +290,29 @@
self.assertEqual(repr(t3),
"datetimetz(2002, 3, 19, 13, 47, tzinfo=met)")
+ def test_combine(self):
+ met = FixedOffset(60, "MET")
+ d = date(2002, 3, 4)
+ tz = timetz(18, 45, 3, 1234, tzinfo=met)
+ dt = datetimetz.combine(d, tz)
+ self.assertEqual(dt, datetimetz(2002, 3, 4, 18, 45, 3, 1234,
+ tzinfo=met))
+
+ def test_extract(self):
+ met = FixedOffset(60, "MET")
+ dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)
+ self.assertEqual(dt.date(), date(2002, 3, 4))
+ self.assertEqual(dt.time(), time(18, 45, 3, 1234))
+ self.assertEqual(dt.timetz(), timetz(18, 45, 3, 1234, tzinfo=met))
+
def test_suite():
- s1 = unittest.makeSuite(TestTimeDelta, 'test')
s2 = unittest.makeSuite(TestDate, 'test')
- s3 = unittest.makeSuite(TestDateTime, 'test')
- s4 = unittest.makeSuite(TestDateTimeTZ, 'test')
- return unittest.TestSuite([s1, s2, s3, s4])
+ s3 = unittest.makeSuite(TestTime, 'test')
+ s4 = unittest.makeSuite(TestTimeTZ, 'test')
+ s5 = unittest.makeSuite(TestDateTime, 'test')
+ s6 = unittest.makeSuite(TestDateTimeTZ, 'test')
+ return unittest.TestSuite([s2, s3, s4, s5, s6])
def test_main():
r = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
=== Zope3/lib/python/datetime/__init__.py 1.2 => 1.3 ===
--- Zope3/lib/python/datetime/__init__.py:1.2 Fri Oct 4 14:05:19 2002
+++ Zope3/lib/python/datetime/__init__.py Mon Dec 2 04:56:11 2002
@@ -5,4 +5,4 @@
# deal with in CVS for now. This __init__ file makes the package look
# like the eventual module.
-from _datetime import timedelta, date, datetime, datetimetz
+from _datetime import timedelta, date, time, timetz, datetime, datetimetz