[Zope3-checkins] CVS: Zope3/lib/python/datetime - __init__.py:1.1.2.1 _datetime.py:1.1.2.1 test_datetime.py:1.1.2.1

Jim Fulton jim@zope.com
Thu, 3 Oct 2002 18:16:53 -0400


Update of /cvs-repository/Zope3/lib/python/datetime
In directory cvs.zope.org:/tmp/cvs-serv27190/lib/python/datetime

Added Files:
      Tag: ZopeDublinCore-branch
	__init__.py _datetime.py test_datetime.py 
Log Message:
Checking in still-unfinished dublin core work on
ZopeDublinCore-branch.

To do:

  - Make a number of existing tests work now that a lot of views 
    need to generate events. (Perhaps these will need to 
    be factored into adapters and views. Sigh.)

  - Make object events able to compute locations for there
    objects when an location hasn't been provided to the constructor.

  - Add some UI for editing at least some meta data.

Handling of lists (e.g. subjects, creators) may need some more thought
as these will often want to come from standard system-provided lists.




=== Added File Zope3/lib/python/datetime/__init__.py ===
# Python datetime `prototype

# This package contains the prototype datetime module that will be included
# in Python 2.3.  We've turned it into a package to make it easier to
# deal with in CVS for now.  This __init__ file makes the package look
# like the eventual module.

from _datetime import timedelta, date, datetime, datetimetz


=== Added File Zope3/lib/python/datetime/_datetime.py === (992/1092 lines abridged)
"""Concrete date/time and related types -- prototype implemented in Python.

See http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage

See also http://dir.yahoo.com/Reference/calendars/
"""

import time as _time
import math as _math

MINYEAR = 1     # XXX The design doc says 0
MAXYEAR = 9999  # XXX The design doc says 65535

# Utility functions, adapted from Python's Demo/classes/Dates.py, which
# also assumes the current Gregorian calendar indefinitely extended in
# both directions.  Difference:  Dates.py calls January 1 of year 0 day
# number 1.  The code here calls January 1 of year 1 day number 1.  This is
# to match the definition of the "proleptic Gregorian" calendar in Dershowitz
# and Reingold's "Calendrical Calculations", where it's the base calendar
# for all computations.  See the book for algorithms for converting between
# proleptic Gregorian ordinals and many other calendar systems.

_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

_DAYS_BEFORE_MONTH = [None]
dbm = 0
for dim in _DAYS_IN_MONTH[1:]:
    _DAYS_BEFORE_MONTH.append(dbm)
    dbm += dim
del dbm, dim

def _is_leap(year):
    "year -> 1 if leap year, else 0."
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def _days_in_year(year):
    "year -> number of days in year (366 if a leap year, else 365)."
    return 365 + _is_leap(year)

def _days_before_year(year):
    "year -> number of days before January 1st of year."
    y = year - 1
    return y*365 + y//4 - y//100 + y//400

def _days_in_month(month, year):
    "month, year -> number of days in that month in that year."
    assert 1 <= month <= 12, month
    if month == 2 and _is_leap(year):
        return 29
    return _DAYS_IN_MONTH[month]

[-=- -=- -=- 992 lines omitted -=- -=- -=-]

        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"
        # XXX What follows could be done more efficiently...
        diff = superself.__sub__(other) + timedelta(minutes=otoff-myoff)
        if diff.days < 0:
            return -1
        if diff == timedelta():
            return 0
        return 1

    def __hash__(self):
        tz = self.__tzinfo
        if tz == None:
            return super(datetimetz, self).__hash__()
        tzoff = tz.utcoffset(self)
        if not tzoff: # zero or None!
            return super(datetimetz, self).__hash__()
        t = self - timedelta(minutes=tzoff)
        return super(datetimetz, t).__hash__()


datetimetz.min = datetimetz(1, 1, 1)
datetimetz.max = datetimetz(9999, 12, 31, 23, 59, 59, 999999)
datetimetz.resolution = timedelta(microseconds=1)


def _isoweek1monday(year):
    # Helper to calculate the day number of the Monday starting week 1
    # XXX This could be done more efficiently
    THURSDAY = 3
    firstday = _ymd2ord(year, 1, 1)
    firstweekday = (firstday + 6) % 7 # See weekday() above
    week1monday = firstday - firstweekday
    if firstweekday > THURSDAY:
        week1monday += 7
    return week1monday


def _test():
    import test_datetime
    test_datetime.test_main()

if __name__ == "__main__":
    _test()


=== Added File Zope3/lib/python/datetime/test_datetime.py === (483/583 lines abridged)
"""Test date/time type.

See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
"""

import sys
import unittest

from datetime import date, datetime, datetimetz, timedelta, 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:

[-=- -=- -=- 483 lines omitted -=- -=- -=-]


    theclass = datetimetz

    def test_zones(self):
        est = FixedOffset(-300, "EST")
        utc = FixedOffset(0, "UTC")
        met = FixedOffset(60, "MET")
        t1 = datetimetz(2002, 3, 19,  7, 47, tzinfo=est)
        t2 = datetimetz(2002, 3, 19, 12, 47, tzinfo=utc)
        t3 = datetimetz(2002, 3, 19, 13, 47, tzinfo=met)
        self.assertEqual(t1.tzinfo, est)
        self.assertEqual(t2.tzinfo, utc)
        self.assertEqual(t3.tzinfo, met)
        self.assertEqual(t1.utcoffset(), -300)
        self.assertEqual(t2.utcoffset(), 0)
        self.assertEqual(t3.utcoffset(), 60)
        self.assertEqual(t1.tzname(), "EST")
        self.assertEqual(t2.tzname(), "UTC")
        self.assertEqual(t3.tzname(), "MET")
        self.assertEqual(hash(t1), hash(t2))
        self.assertEqual(hash(t1), hash(t3))
        self.assertEqual(hash(t2), hash(t3))
        self.assertEqual(t1, t2)
        self.assertEqual(t1, t3)
        self.assertEqual(t2, t3)
        self.assertEqual(str(t1), "2002-03-19 07:47:00.000000-05:00")
        self.assertEqual(str(t2), "2002-03-19 12:47:00.000000+00:00")
        self.assertEqual(str(t3), "2002-03-19 13:47:00.000000+01:00")
        self.assertEqual(repr(t1),
                         "datetimetz(2002, 3, 19, 7, 47, tzinfo=est)")
        self.assertEqual(repr(t2),
                         "datetimetz(2002, 3, 19, 12, 47, tzinfo=utc)")
        self.assertEqual(repr(t3),
                         "datetimetz(2002, 3, 19, 13, 47, 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])

def test_main():
    r = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
    s = test_suite()
    r.run(s)

if __name__ == "__main__":
    test_main()