From: Daniele Varrazzo Date: Wed, 2 Jun 2021 10:42:12 +0000 (+0100) Subject: Add c timetz binary loader X-Git-Tag: 3.0.dev0~39^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e2b7cf7aad84df23a269bd6cdc460a81b5fb8498;p=thirdparty%2Fpsycopg.git Add c timetz binary loader --- diff --git a/psycopg3_c/psycopg3_c/types/date.pyx b/psycopg3_c/psycopg3_c/types/date.pyx index 0fb30d47a..1475495de 100644 --- a/psycopg3_c/psycopg3_c/types/date.pyx +++ b/psycopg3_c/psycopg3_c/types/date.pyx @@ -578,6 +578,39 @@ cdef class TimetzLoader(CLoader): raise e.DataError(f"can't parse timetz {s!r}: {ex}") from None +@cython.final +cdef class TimetzBinaryLoader(CLoader): + + format = PQ_BINARY + + cdef object cload(self, const char *data, size_t length): + cdef int64_t val = endian.be64toh((data)[0]) + cdef int32_t off = endian.be32toh(((data + sizeof(int64_t)))[0]) + cdef int h, m, s, ms + + with cython.cdivision(True): + ms = val % 1_000_000 + val //= 1_000_000 + + s = val % 60 + val //= 60 + + m = val % 60 + h = val // 60 + + # Python < 3.7 didn't support seconds in the timezones + if PY_VERSION_HEX >= 0x03070000: + off = off // 60 * 60 + + tz = timezone_from_seconds(-off) + try: + return cdt.time_new(h, m, s, ms, tz) + except ValueError: + raise e.DataError( + f"time not supported by Python: hour={h}" + ) from None + + cdef object timezone_from_seconds(int sec, __cache={}): cdef object pysec = sec cdef PyObject *ptr = PyDict_GetItem(__cache, pysec)