The postgresql Time type supports times from "00:00:00" to "24:00:00" in 
accordance with ISO 8601 <http://en.wikipedia.org/wiki/ISO_8601#Times>. 
 The python datetime.time class does not currently support "24:00:00" but 
it would be useful to have SQLAlchemy support that.  I'm using SQLAlchemy 
0.6.8 and was wondering if there is a way to allow it to support the 
"24:00:00" midnight notation.

I've tried to make a custom type that would support it, but it seems that 
psycopg2 will return a datetime.time class even if I define the custom type 
to implement the Text type.


from datetime import timedelta

from sqlalchemy.types import TypeDecorator, Text


class Time(timedelta):
    """Time class that supports times between "00:00:00" and "24:00:00"
    inclusive."""

    SEC_PER_MIN = 60
    SEC_PER_HOUR = SEC_PER_MIN * 60
    SEC_PER_DAY = SEC_PER_HOUR * 24

    def __new__(cls, hour=0, minute=0, second=0):
        seconds = hour * cls.SEC_PER_HOUR + minute * cls.SEC_PER_MIN + 
second
        instance = timedelta.__new__(cls, 0, seconds)
        if not (timedelta(0) <= instance <= timedelta(1)):
            raise ValueError('Values must be between 00:00:00 and 
24:00:00.')
        return instance

    def __str__(self):
        return '{0.hour:02}:{0.minute:02}:{0.second:02}'.format(self)

    def __repr__(self):
        return '{0}({1.hour}, {1.minute}, {1.second})'.format(
                type(self).__name__, self)

    @property
    def hour(self):
        seconds = self.days * self.SEC_PER_DAY + self.seconds
        return seconds / self.SEC_PER_HOUR

    @property
    def minute(self):
        return self.seconds % self.SEC_PER_HOUR / self.SEC_PER_MIN

    @property
    def second(self):
        return self.seconds % self.SEC_PER_MIN

    @classmethod
    def parse(cls, time):
        return Time(*[int(x) for x in time.split(':')])


class TimeOfDay(TypeDecorator):
    """Time type that handles times between 00:00:00 and 24:00:00."""

    impl = Text

    def process_bind_param(self, value, dialect):
        """Store time as a string."""
        if value is None:
            return None

        return str(value)

    def process_result_value(self, value, dialect):
        """Return Time object."""
        if value is None:
            return None

        return Time.parse(value)


This would work if the actual database column was Text but in the postgres 
database the column is Time.  So it seems that psycopg2 converts that 
automatically to a datetime.time when retrieving the value, which makes the 
time "24:00:00" be "00:00:00".

Thanks for any input,
-Will Weaver

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/aZWWaRa8vBgJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to