Support for seconds in time zone offsets

This commit is contained in:
Federico Di Gregorio 2009-03-02 11:07:17 +01:00
parent 5b04203c9f
commit 1daf300ca3
2 changed files with 52 additions and 0 deletions

View File

@ -1,5 +1,8 @@
2009-03-02 Federico Di Gregorio <fog@initd.org> 2009-03-02 Federico Di Gregorio <fog@initd.org>
* Applied modified patch from Karsten Hilbert to provide a
type-caster able to parse times with seconds in the time zone.
* Applied patch from Menno Smits to avoid problems with DictCursor * Applied patch from Menno Smits to avoid problems with DictCursor
when the query is executed by a named cursor. Also added Menno's when the query is executed by a named cursor. Also added Menno's
tests and uniformed other DictCursor tests. tests and uniformed other DictCursor tests.

View File

@ -360,4 +360,53 @@ def register_inet(oid=None, conn_or_curs=None):
return _ext.INET return _ext.INET
# safe management of times with a non-standard time zone
def _convert_tstz_w_secs(s, cursor):
try:
return DATETIME(s, cursor)
except (DataError,), exc:
if exc.message != "unable to parse time":
raise
if regex.match('(\+|-)\d\d:\d\d:\d\d', s[-9:]) is None:
raise
# parsing doesn't succeed even if seconds are ":00" so truncate in
# any case
return DATETIME(s[:-3], cursor)
def register_tstz_w_secs(oids=None, conn_or_curs=None):
"""Register alternate type caster for TIMESTAMP WITH TIME ZONE.
The Python datetime module cannot handle time zones with
seconds in the UTC offset. There are, however, historical
"time zones" which contain such offsets, eg. "Asia/Calcutta".
In many cases those offsets represent true local time.
If you encounter "unable to parse time" on a perfectly valid
timestamp you likely want to try this type caster. It truncates
the seconds from the time zone data and retries casting
the timestamp. Note that this will generate timestamps
which are INACCURATE by the number of seconds truncated
(unless the seconds were 00).
<oids>
which OIDs to use this type caster for,
defaults to TIMESTAMP WITH TIME ZONE
<conn_or_curs>
a cursor or connection if you want to attach
this type caster to that only, defaults to
None meaning all connections and cursors
"""
if oids is None:
oids = (1184,) # hardcoded from PostgreSQL headers
_ext.TSTZ_W_SECS = _ext.new_type(oids, 'TSTZ_W_SECS', _convert_tstz_w_secs)
_ext.register_type(TSTZ_W_SECS, conn_or_curs)
return _ext.TSTZ_W_SECS
__all__ = [ k for k in locals().keys() if not k.startswith('_') ] __all__ = [ k for k in locals().keys() if not k.startswith('_') ]