diff --git a/psycopg/typecast_datetime.c b/psycopg/typecast_datetime.c index 6b94175e..6f063082 100644 --- a/psycopg/typecast_datetime.c +++ b/psycopg/typecast_datetime.c @@ -220,7 +220,7 @@ typecast_PYTIME_cast(const char *str, Py_ssize_t len, PyObject *curs) static PyObject * typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs) { - long years = 0, months = 0, days = 0, sec; + long years = 0, months = 0, days = 0, lsec; double hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0; double v = 0.0, sign = 1.0, denominator = 1.0; int part = 0; @@ -317,10 +317,10 @@ typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs) /* calculates days */ days += years*365 + months*30; - micro = (seconds - floor(seconds)) * 1000000.0; - sec = (long)floor(seconds); + lsec = (long)seconds; + micro = (seconds - (double)lsec) * 1000000.0; return PyObject_CallFunction((PyObject*)PyDateTimeAPI->DeltaType, "lli", - days, sec, (int)round(micro)); + days, lsec, (int)round(micro)); } /* psycopg defaults to using python datetime types */ diff --git a/tests/test_dates.py b/tests/test_dates.py index 8bb03c79..10009979 100755 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -334,8 +334,27 @@ class DatetimeTests(ConnectingTestCase, CommonDatetimeTestsMixin): self.assertEqual(t, time(0, 0, tzinfo=FixedOffsetTimezone(330))) def test_large_interval(self): + def total_seconds(d): + """Return total number of seconds of a timedelta as a float.""" + return d.days * 24 * 60 * 60 + d.seconds + d.microseconds / 1000000.0 + t = self.execute("select '999999:00:00'::interval") - self.assertEqual(t.days * 24 + t.seconds / 60.0 / 60, 999999) + self.assertEqual(total_seconds(t), 999999 * 60 * 60) + + t = self.execute("select '-999999:00:00'::interval") + self.assertEqual(total_seconds(t), -999999 * 60 * 60) + + t = self.execute("select '999999:00:00.1'::interval") + self.assertEqual(total_seconds(t), 999999 * 60 * 60 + 0.1) + + t = self.execute("select '999999:00:00.9'::interval") + self.assertEqual(total_seconds(t), 999999 * 60 * 60 + 0.9) + + t = self.execute("select '-999999:00:00.1'::interval") + self.assertEqual(total_seconds(t), -999999 * 60 * 60 - 0.1) + + t = self.execute("select '-999999:00:00.9'::interval") + self.assertEqual(total_seconds(t), -999999 * 60 * 60 - 0.9) # Only run the datetime tests if psycopg was compiled with support.