Re: problem with timezone parsing

James Henstridge <[email protected]>
Newsgroups gmane.comp.python.db.psycopg.devel
Message-ID <[email protected]>
On Wed, Feb 18, 2009 at 1:51 AM, Karsten Hilbert
<[email protected]> wrote:
> On Tue, Feb 17, 2009 at 05:00:53PM +0100, Federico Di Gregorio wrote:
>
>> > Is there a way to install a module wide type caster ?
> ...
>> Yes, just don't pass that parameter or pass None.
> ...
>> > Is there a way to not need to access the DB (for learning
>> > the type OID) and still use new_type (which seems a
>> > prerequisite for register_type).
>>
>> If you know the oid you can hard-code it into your code.
> ...
>> > Thereby the second question can be answered yes but needs
>> > reconfirmation that re-using those OIDs is reasonably safe ?
>>
>> It is completely safe. They are generated from your PostgreSQL headers
>> and guaranteed to be stable.
>
> Thanks for all the help and comments. This is what I came up
> with. It works for me:
>
>
>
> # ----------------------------------------------------------------------
> # PostgreSQL -> Python
> # ----------------------------------------------------------------------
>
> # we need this because some places once used time "zones"
> # with true local time, IOW having seconds in the UTC offset,
> # the Python datetime zone code cannot handle that, however,
> # which makes psycopg2 fail when loading timestamps with such
> # time zones from the backend ...,
> # so we (almost) silently drop the seconds
> def convert_ts_with_odd_tz(string_value, cursor):
>        try:
>                return dbapi.DATETIME(string_value, cursor)
>        except dbapi.DataError:
>                _log.error('unable to parse [%s] as <timestamp with time zone>', string_value)
>                if regex.match('(\+|-)\d\d:\d\d:\d\d', string_value[-9:]) is not None:
>                        # parsing doesn't succeed even if seconds
>                        # are ":00" so truncate in any case
>                        _log.debug('time zone with seconds detected (true local time ?)')
>                        adjusted_string_value = string_value[:-3]
>                        _log.warning('truncating to [%s] and trying again', adjusted_string_value)
>                        _log.warning('value will be off by %s seconds', string_value[-2:])
>                        return dbapi.DATETIME(adjusted_string_value, cursor)
>                raise
>
> DT_W_ODD_TZ = psycopg2.extensions.new_type(dbapi.DATETIME.values, 'DT_W_ODD_TZ', convert_ts_with_odd_tz)
> psycopg2.extensions.register_type(DT_W_ODD_TZ)
>
>
>
> Hope that helps someone down the line !

Note that in released versions of psycopg2, the DATETIME caster will
sometimes succeed but give an incorrect result (any negative UTC
offset that isn't a whole number of hours).  So you might be best off
doing the time zone parsing yourself if it is important to you.

James.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.