[DB-SIG] ODMG Date/time classes

Jim Fulton jim.fulton@digicool.com
Wed, 17 Dec 1997 16:20:58 -0500


This is a multi-part message in MIME format.

--------------470D371E61B2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

As promised, I'm providing skeleton python classes that
describe the interfaces to the standard date-time related
types defined by the Object Data Management Group (ODMG)
standard.  I beleave these are based on possibly SQL standards, 
although I can't provide a reference.

I prefer this interface to the interface proposed by M.-A. Lemburg
because:

  - It is a standard,
  
  - It handles time zones in a reasonable minimal manner,

  - It provides for separation of date, time, and interval,

  - It supports date/time arithmetic,

  - It provides information hiding (the implementation is not
    exposed)

Jim

-- 
Jim Fulton           mailto:jim@digicool.com
Technical Director   (888) 344-4332             Python Powered!
Digital Creations    http://www.digicool.com    http://www.python.org

--------------470D371E61B2
Content-Type: text/plain; charset=us-ascii; name="ODMG-Date.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ODMG-Date.py"

  
class Interval:
    """Duration of time

    The Interval class is used to represent a duration of time. It is
    also used to perform arithmetic operations on Date, Time, and
    Timestamp classes.  This class corresponds to the date-time
    interval as defined in the SQL standard.

    The Interval class accepts nonnormalized input, but normalizes
    the time components when accessed.  For example, the constructor
    would accept 28 hours as input, but then calling the day method
    would return a value of 1 and the hour method would return a
    value of 4.  Arithmetic would work in a similar manner.
    """

    def __init__(self, day=0, hour=0, min=0, sec=0.0):
	"""Initialize an Interval

	An alternate signature may be used to initialize an Interval
	from an existing Interval:

	  Interval(anInterval)
	"""

    def day(self):
	"""Return the day part of the interval"

    def hour(self):
	"""Return the hour part of the interval"

    def minute(self):
	"""Return the minute part of the interval"

    def second(self):
	"""Return the seconds part of the interval"

    def is_zero(self):
	"""Return true if all of the interval parts are zero

	Return false otherwise.
	"""

    def __nonzero__(self):
	"""Return true if any of the interval parts are nonzero

	Return false otherwise.
	"""

    def __neg__(self):
	"""Return the Interval negated"""

    def __pos__(self):
	"""Return the Interval"""

    def __add__(self, anInterval):
	"""Add two intervals"""

    def __sub__(self, anInterval):
	"""Subtract two intervals"""
    
    def __mul__(self, anInt):
	"""Multiply an interval by an integer"""

    __rmul__=__mul__

    def __div__(self, anInt):
	"""Divide an interval by an integer"""
    
    def __mod__(self, anInt):
	"""Return the remainder of division by an integer"""
    
    def __divmod__(self, anInt):
	"""Return the result and remainder of division by an integer"""

    def __cmp__(self, anInterval):
	"""Compare two intervals"""

    def __hash__(self):
	"""Return a hash value"""

class _DateStatic:
    """Static Date functions

    This class is not a part of the public interface, but the methods
    defined below are "static" methods of the (public) Date class.
    """

    def current(self):
	"""Return the current date"

    def is_leap_year(self, year):
	"""Return true if the given year is a leap year, and false otherwise"

    def days_in_year(self, year):
	"""Return the number of days in the year"
	
    def days_in_month(self, year, month):
	"""Return the number of days in the month of the year"

    def is_valid_date(self, year, month, day):
	"""Test whether the given year, month, and day are valid"

_DateStatic=_DateStatic()

class Date:
    """Dates

    The Date class stores a representation of a date consisting of
    a year, month and day.  It also provides enumerations to denote
    weekdays and months.

    Days within a month or year are numbered from 1, as are months.
    """

    [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
     ] = range(7)

    [January, February, March, April, May, June,
     July, August, September, October, November, December
     ] = range(1,13)

    def __init__(self, *args):
	"""Initialize a date

	A number of different signatures are supported:

	  Date() -- Initialize to the current date.

	  Date(aDateOrTimestamp) --
	    Initialize from an existing Date or Timestamp

	  Date(aTimeTime) --
	    Initialize from a value of the type
	    returned by the 'time' function of the 'time' module.

	  Date(year, day_of_year) --
	    Initialize from a year and a day within the year.

	  Date(year, month, day) --
	    initialize from a year, month, and day.

	if the specified date inputs are invalid, a DateInvalidError
	exception is raised.
	"""

    def year(self):
	"""Return the year component of the date"""

    def month(self):
	"""Return the month component of the date"""

    def day(self):
	"""Return the day (in the month) component of the date"""

    def day_of_year(self):
	"""Return the day within the year"""

    def day_of_week(self):
	"""Return the day within the week as an integer"""

    month_of_year=month

    def is_leap_year(self):
	"""Return true if the date\'s year is a leap year, and false otherwise"

    def next(self, aDayOfWeek):
	"""Advance the date to the next date that falls on the day of the week

	The date is modified and returned"

    def previous(self, aDayOfWeek):
	"""Back the date to the next date that falls on the day of the week

	The date is modified and returned"

    def increment(self, days):
	"""Advance the date the given number of days

	The date is modified and returned"

    def deccrement(self, days):
	"""Back the date the given number of days

	The date is modified and returned"

    def __add__(self, anInterval):
	"""Add an Interval, returning a new Date"""
    __radd__=__add__

    def __sub__(self, anIntervalOrDate):
	"""Subtract a Date or an Interval

	If subtracting an Interval, a Date is returned.

	If subtracting a Date, an Interval is returned.
	"""

    def __cmp__(self, aDate):
	"""Compare two dates"""

    def __hash__(self):
	"""Return a hash code"""

    def is_between(self, aDate, anotherDate):
	"""Return true if the date is between 'aDate' and 'anotherdate'.

	Return false otherwise.
	"""

    def days_in_year(self):
	"""Return the number of days in the year"

    def days_in_month(self):
	"""Return the number of days in the month"

    current=_DateStatic.current
    is_leap_year=_DateStatic.is_leap_year
    days_in_year=_DateStatic.days_in_year
    days_in_month=_DateStatic.days_in_month
    is_valid_date=_DateStatic.is_valid_date

    class DateInvalidError:
	"""Exception class for invalid date creation parameters"""

class _TimeStatic:
    """Static Time Functions

    This class is not a part of the public interface, but the methods
    defined below are "static" methods of the (public) Time class.
    """
        
    def default_Time_Zone(self):
	"""Get the default time zone hours offset"""
        
    def default_Time_Zone_minutes(self):
	"""Get the default time zone minutes offset"""
        
    def set_default_Time_Zone(self, hours, minutes=0):
	"""Set the default time zone (offset from GMT)"""

    def set_default_Time_Zone_to_local(self):
	"""Set the default time zone to the local time zone"""

    def current():
	"""Return the current time as a Time using the default
	time zone"

_TimeStatic=_TimeStatic()

class Time:
    """Denote a specific time

    The Time class is used to denote a specific time, which is
    internally stored in Greenwich Mean Time (GMT).
    """
    [
     GMT_11, GMT_10, GMT_9, GMT_8, GMT_7, GMT_6,
     GMT_5, GMT_4, GMT_3, GMT_2, GMT_1, GMT,
     GMT1, GMT2, GMT3, GMT4, GMT5, GMT6,
     GMT7, GMT8, GMT9, GMT10, GMT11,
     ]  range(-11,12)
    USeastern, UScentral, USmountain, USpacific = -5, -6, -7, -8

    def __init__(self, *args):
	"""Initialize a Time

	A number of different signatures are supported:

	  Time() -- initialize to current time (and default time zone)

	  Time(aTimeOrTimestamp) -- Initialize from a Time or Timestamp

	  Time(hour, minute, second=0, tz_hour=None, tz_minute=None) --

	    Initialize from given hour, minute, second, and time-zone
	    offset in hours and minutes. 

	    If the time zone is not specified, then the default time
	    zone is used.  If tz_hour is specified, then
	    tz_minute defaults to 0.
	"""

    def hour(self):
	"Return the hour component of the Time"

    def minute(self):
	"Return the minute component of the Time"

    def second(self):
	"Return the second component of the Time"

    def tz_hour(self):
	"Return the time-zone hour component"

    def tz_minute(self):
	"Return the time-zone minute component"

    def __add__(self, anInterval):
	"""Add an Interval"""
    __radd__=__add__

    def __sub__(self, anIntervalOrTime):
	"""Subtract a Time or an Interval

	If a Time is subtracted, then an Interval is returned.
	If an Interval is subtracted, then a Time is returnd
	(modulo 24 hours).
	"""

    def __cmp__(self, aTime):
	"""Compare two Times"""

    def __hash__(self):
	"""Return a hash code"""

    class TimeInvalidError:
	"""Exception class for invalid Time creation parameters"""

    default_Time_Zone=_TimeStatic.default_Time_Zone
    set_default_Time_Zone=_TimeStatic.set_default_Time_Zone
    set_default_time_Zone_to_local=_TimeStatic.set_default_Time_Zone_to_local
    current=_TimeStatic.current
    

class _TimestampStatic:
    """Static Timestamp Functions

    This class is not a part of the public interface, but the methods
    defined below are "static" methods of the (public) Timestamp class.
    """

    def current():
	"""Return the current time as a Timestamp"

_TimestampStatic=_TimestampStatic()

class Timestamp:
    """A Timestamp models a point in time as a Date and a Time"""

    def __init__(self, *args):
	"""Initialize a Timestamp

	A number of different signatures are supported:

	  Timestamp() -- Initialize to current time, using the default
	     time zone.

	  Timestamp(year, month=1, day=1, hour=0, minute=0, second=0.0,
	            tzhours=None, tzminutes=None) --
	     Initialize from a year, month, day, hour, minute, and
	     time zone. If the time zone is not specified, then the
	     default time zone is used. If tzhours is specified, then
	     tzminutes defaults to 0.
  
	  Timestamp(aDate, aTime) -- Initialize from a Date and Time

	  Timestamp(Timestamp) -- Initialize from a Timestamp

	  Timestamp(aTimeTime, tzhours=None, tzminutes=None) --
	    Initialize from a value of the type returned by the 'time'
	    function of the 'time' module, and the local time zone.
	    If the time zone is not specified, then the default time zone
	    is used. If tzhours is specified, then tzminutes defaults to 0.
	"""

    def date(self):
	"""Return the Date component"

    def time(self):
	"""Return the time component"

    def year(self):
	"""Return the year component of the date"""

    def month(self):
	"""Return the month component of the date"""

    def day(self):
	"""Return the day (in the month) component of the date"""

    def hour(self):
	"Return the hour component of the Time"

    def minute(self):
	"Return the minute component of the Time"

    def second(self):
	"Return the second component of the Time"

    def tz_houre(self):
	"Return the time-zone hour component"

    def tz_minute
	"Return the time-zone minute component"

    def __add__(self, anInterval):
	"""Add an Interval"""
    __radd__=__add__

    def __sub__(self, anIntervalOrTime):
	"""Subtract a Timestamp or an Interval"""

    def __cmp__(self, aTimestamp):
	"""Compare two Timestamps"""

    def __hash__(self):
	"""Return a hash code"""

    class TimestampInvalidError:
	"""Exception class for invalid Timestamp creation parameters"""

    current=_TimeStatic.current

def overlaps(s1,e1,s2,e2):
    """Determine wether two periods overlap.

    The first period is defined by either two Dates, two Times,
    or two Timestamps s1, and e1.

    The second period is defined by either two Dates, two Times,
    or two Timestamps s1, and e1.

    This function is not defined for combinations of two Dates and two
    Times.
    """

--------------470D371E61B2--


_______________
DB-SIG  - SIG on Tabular Databases in Python

send messages to: db-sig@python.org
administrivia to: db-sig-request@python.org
_______________