如何用psycopg2(PostgreSQL)比较日期?

时间:2014-05-05 11:06:33

标签: python postgresql datetime timestamp psycopg2

通过使用PostgreSQL Python模块psycopg2,我想找到一些结束时间落在某个时间戳之前的行。我尝试使用带有cursor.execute(…)的SQL查询的… where end_time < %s执行此操作,其中%s替换为带有时区的datetime.datetime对象。 psycopg2生成的SQL是:

select * from my_table where end_time < '2014-05-01T13:00:00+00:00'::timestamptz;

返回如下行:

id  |     start_time      |      end_time       
331 | 2014-05-01 14:55:00 | 2014-05-01 15:05:00

结束时间不早于2014-05-01 at 13:00 UTC,与我的预期相反。

在psycopg2中执行所需时间选择的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

好的,在中使用PostgreSQL时间戳和时区解决了这个问题。

以下是问题所在的详细信息:

  • 我将时区感知时间戳放在不支持时区的列中。我假设timestamp without time zone列包含 UTC 时间(例如timestamp with time zone),但它实际上包含本地中的时间戳时间,如documentation

    中所述
      

    没有时区的时间戳和时间戳之间的转换   时区通常假设时间戳没有时区值   应当作为当地时间的时区采取或给出。不同的时区   可以使用AT TIME ZONE指定转换。

    因此,在中国时,00:00 UTC将08:00存储在timestamp without time zone列中。

  • 执行比较时,如#34;时间戳,不带时区&#34; &LT; &#34; timestamp with time zone&#34;,我无法在文档中找到PostgreSQL的功能。然而,在该问题中观察到的结果与首先以相同方式移除时区的想法一致,并且比较了没有时区的时间戳。我不应该对结果感到惊讶:迟到的时间&#34; 15:00&#34;确实早于而不是13:00 UTC,在中国(UTC + 8)。关键是要知道显示(和存储)时间是在当地时区。

我从中得到的道德是:有时区和无时区的时间戳之间的转换可以更好地处理显式

答案 1 :(得分:0)

指定应显示时间的时区。如果start_timeend_time是时间戳没有时区,那么您还需要告诉postgresql他们应该在哪个时区

select 
    id,
    start_time at time zone 'UTC' at time zone 'UTC',
    end_time at time zone 'UTC' at time zone 'UTC'
from my_table 
where end_time at time zone 'UTC' < %s