9

How can you express an infinite timedelta in Python?

Up to now we use datetime from stdlib, but we could switch, if it is only supported in a third party library.

PostgreSQL does support it. And it would be handy in my case. I want to use it to express an not finished interval.

I could use None, but an infinite timedelta could avoid a lot of conditions (if statements).

guettli
  • 25,042
  • 81
  • 346
  • 663
  • 2
    An infinite timedelta? O_o so the result of `datetime.now() + infinite_timedelta` should be...what? `infinitely_in_the_future`? – Ffisegydd Jan 20 '15 at 10:13
  • 1
    Infinite time seems pretty undefined, so perhaps use `None`. –  Jan 20 '15 at 10:14
  • 2
    Maybe we should take a step back, what are you trying to accomplish with an infinite timedelta? – OldTinfoil Jan 20 '15 at 10:17
  • Why do you need it anyway? All the information present so far shows little practical use for such a thing. You'd probably be better off with something different. – ivan_pozdeev Jan 20 '15 at 10:20
  • @IntrepidBrit I updated the question: I want to use it to express an not finished interval. – guettli Jan 20 '15 at 10:22
  • Then surely as @Evert suggests, using `None` would do the trick instead.. – OldTinfoil Jan 20 '15 at 10:25
  • Or just use the maximum representable value for timedelta or something that's sufficiently large - if you're allergic to if statements – OldTinfoil Jan 20 '15 at 10:29
  • Simple way - use `datetime` stating the timedelta's start if you do not have it's end yet. The *right* way would probably be to use a class with two datetime objects. – Reut Sharabani Jan 20 '15 at 10:44

3 Answers3

3

I found this: http://initd.org/psycopg/docs/usage.html#infinite-dates-handling

PostgreSQL can store the representation of an “infinite” date, timestamp, or interval. Infinite dates are not available to Python, so these objects are mapped to date.max, datetime.max, interval.max. Unfortunately the mapping cannot be bidirectional so these dates will be stored back into the database with their values, such as 9999-12-31.

Short answer: not supported.

guettli
  • 25,042
  • 81
  • 346
  • 663
  • I opened a feature request for support of infinity in psycopg2: https://github.com/psycopg/psycopg2/issues/283 – guettli Jan 26 '15 at 08:10
1

The typical way to express an unfinished interval is to use a datetime type's maximum value or NULL for the ending time.

As it was shown, you cannot really perform calculations involving the infinite value and get meaningful results.

Thus, NULL is better in this regard by simply not allowing you to.

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
1

An "unfinished interval" can be expressed with datetime (and possibly subclass it to contain a flag stating start or end) - that's what I would do for a quick implementation.

When you have the interval's corresponding end or start), get the timedelta using their difference:

>>> from datetime import datetime, timedelta
# represent infinite time from 1/1/2014 onwards
>>> start = datetime(2014, 1, 1)
# stop that time
>>> end = datetime(2015, 1, 1)
>>> interval = end - start
>>> interval
datetime.timedelta(365)

If you have the time to do this "the right way" you can create a speacialized timedelta-like class with two datetime objects (start and end). If one of them is missing you can assume it's an infinite timedelta and treat it as such.

Example:

from datetime import timedelta, datetime
class SpecialTimedelta(object):

    def __init__(self, start=None, end=None):
        self.start = start
        self.end = end

        if start and not isinstance(start, datetime):
            raise TypeError("start has to be of type datetime.datetime")
        if end and not isinstance(start, datetime):
            raise TypeError("end has to be of type datetime.datetime")

    def timedelta(self):
        if not (self.start and self.end):
            # possibly split cases
            return "infinite"
            # alternatives:
            # return self.start or self.end
            # raise OverflowError("Cannot quantiate infinite time with timedelta")
        return self.end - self.start

print SpecialTimedelta(datetime(1986, 1, 1), datetime(2015, 1, 1)).timedelta()
# out: 10592 days, 0:00:00
print SpecialTimedelta(datetime(1986, 1, 1)).timedelta()
# out: infinite
Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88