mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-21 16:36:34 +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`).
|
||||
- Added `~psycopg2.extras.Json` `!prepare()` method to consider connection
|
||||
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.
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
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",
|
||||
days, seconds, micros);
|
||||
}
|
||||
|
|
|
@ -223,6 +223,32 @@ class DatetimeTests(ConnectingTestCase, CommonDatetimeTestsMixin):
|
|||
def test_parse_negative_interval(self):
|
||||
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):
|
||||
value = self.DATETIME('-infinity', self.curs)
|
||||
self.assertEqual(str(value), '0001-01-01 00:00:00')
|
||||
|
|
Loading…
Reference in New Issue
Block a user