mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-24 18:03:43 +03:00
Add 6 hours per year converting from interval
This is the same operation performed by postgres when extracting the number of seconds of an interval: =# select extract(epoch from '1 year'::interval) / 60 / 60 / 24; ?column? ---------- 365.25 This way `extract(epoch from interval)` will match the resulting `timedelta.total_seconds()`. Close #570
This commit is contained in:
parent
45f7ec73be
commit
7254587838
4
NEWS
4
NEWS
|
@ -24,6 +24,10 @@ What's new in psycopg 2.7.2
|
||||||
- Parse intervals returned as microseconds from Redshift (:ticket:`#558`).
|
- Parse intervals returned as microseconds from Redshift (:ticket:`#558`).
|
||||||
- Added `~psycopg2.extras.Json` `!prepare()` method to consider connection
|
- Added `~psycopg2.extras.Json` `!prepare()` method to consider connection
|
||||||
params when adapting (:ticket:`#562`).
|
params when adapting (:ticket:`#562`).
|
||||||
|
- Convert PostgreSQL :sql:`interval` containing years and months into
|
||||||
|
Python `~datetime.timedelta` with `!total_seconds()` matching the
|
||||||
|
:sql:`interval` epoch, i.e. add 6 hours every year or 12 months
|
||||||
|
(:ticket:`#570`).
|
||||||
- `~psycopg2.errorcodes` map updated to PostgreSQL 10 beta 1.
|
- `~psycopg2.errorcodes` map updated to PostgreSQL 10 beta 1.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -448,6 +448,9 @@ typecast_PYINTERVAL_cast(const char *str, Py_ssize_t len, PyObject *curs)
|
||||||
/* add the days, months years together - they already include a sign */
|
/* add the days, months years together - they already include a sign */
|
||||||
days += 30 * (PY_LONG_LONG)months + 365 * (PY_LONG_LONG)years;
|
days += 30 * (PY_LONG_LONG)months + 365 * (PY_LONG_LONG)years;
|
||||||
|
|
||||||
|
/* Postgres adds 6 hours for each year, or for each 12 months */
|
||||||
|
seconds += 6 * 60 * 60 * (PY_LONG_LONG)(years + (months / 12));
|
||||||
|
|
||||||
return PyObject_CallFunction((PyObject*)PyDateTimeAPI->DeltaType, "LLl",
|
return PyObject_CallFunction((PyObject*)PyDateTimeAPI->DeltaType, "LLl",
|
||||||
days, seconds, micros);
|
days, seconds, micros);
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,32 @@ class DatetimeTests(ConnectingTestCase, CommonDatetimeTestsMixin):
|
||||||
def test_parse_negative_interval(self):
|
def test_parse_negative_interval(self):
|
||||||
self._check_interval('-42 days -12:34:56.123456')
|
self._check_interval('-42 days -12:34:56.123456')
|
||||||
|
|
||||||
|
def test_parse_mixied_signs_interval(self):
|
||||||
|
# Intervals in postgres have 4 blocks
|
||||||
|
# -1 year -2 mons +3 days -04:05:06
|
||||||
|
# each can be missing, present with no sign, positive, negative
|
||||||
|
# test all the combos
|
||||||
|
def cases(s):
|
||||||
|
return ['', s, '-' + s, '+' + s]
|
||||||
|
|
||||||
|
from itertools import product
|
||||||
|
for parts in product(
|
||||||
|
cases('1 year'), cases('2 months'),
|
||||||
|
cases('3 days'), cases('04:05:06')):
|
||||||
|
s = ' '.join(parts)
|
||||||
|
if s.isspace():
|
||||||
|
continue
|
||||||
|
self._check_interval(s)
|
||||||
|
|
||||||
|
def test_parse_interval_element(self):
|
||||||
|
for i in range(-1000, 1100, 100):
|
||||||
|
self._check_interval('%s years' % i)
|
||||||
|
self._check_interval('%s months' % i)
|
||||||
|
self._check_interval('%s days' % i)
|
||||||
|
self._check_interval('%s hours' % i)
|
||||||
|
self._check_interval('%s minutes' % i)
|
||||||
|
self._check_interval('%s seconds' % i)
|
||||||
|
|
||||||
def test_parse_infinity(self):
|
def test_parse_infinity(self):
|
||||||
value = self.DATETIME('-infinity', self.curs)
|
value = self.DATETIME('-infinity', self.curs)
|
||||||
self.assertEqual(str(value), '0001-01-01 00:00:00')
|
self.assertEqual(str(value), '0001-01-01 00:00:00')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user