Try to fix the same problem in windows

Previous commit doesn't pass on Windows: it looks like window's floor()
has an integer overflow.
This commit is contained in:
Daniele Varrazzo 2017-02-24 02:41:34 +01:00
parent 14fe3ad8c9
commit a15dfbbd4f
2 changed files with 24 additions and 5 deletions

View File

@ -220,7 +220,7 @@ typecast_PYTIME_cast(const char *str, Py_ssize_t len, PyObject *curs)
static PyObject * static PyObject *
typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs) 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 hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0;
double v = 0.0, sign = 1.0, denominator = 1.0; double v = 0.0, sign = 1.0, denominator = 1.0;
int part = 0; int part = 0;
@ -317,10 +317,10 @@ typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs)
/* calculates days */ /* calculates days */
days += years*365 + months*30; days += years*365 + months*30;
micro = (seconds - floor(seconds)) * 1000000.0; lsec = (long)seconds;
sec = (long)floor(seconds); micro = (seconds - (double)lsec) * 1000000.0;
return PyObject_CallFunction((PyObject*)PyDateTimeAPI->DeltaType, "lli", return PyObject_CallFunction((PyObject*)PyDateTimeAPI->DeltaType, "lli",
days, sec, (int)round(micro)); days, lsec, (int)round(micro));
} }
/* psycopg defaults to using python datetime types */ /* psycopg defaults to using python datetime types */

View File

@ -334,8 +334,27 @@ class DatetimeTests(ConnectingTestCase, CommonDatetimeTestsMixin):
self.assertEqual(t, time(0, 0, tzinfo=FixedOffsetTimezone(330))) self.assertEqual(t, time(0, 0, tzinfo=FixedOffsetTimezone(330)))
def test_large_interval(self): 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") 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. # Only run the datetime tests if psycopg was compiled with support.