【问题标题】:How to compare dates with psycopg2 (PostgreSQL)?如何与 psycopg2 (PostgreSQL) 比较日期?
【发布时间】:2014-06-21 15:58:54
【问题描述】:

通过使用 PostgreSQL Python 模块 psycopg2,我想查找结束时间在某个时间戳之前的行。我尝试在带有… where end_time < %s 的SQL 查询中使用cursor.execute(…) 来执行此操作,其中%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 年 5 月 1 日 13:00 UTC,与我的预期相反。

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

【问题讨论】:

  • 您确定没有将时间转换为当地时间进行显示吗? end_time 的 UTC 值是多少?
  • 我知道这些时间是 UTC:select end_time at time zone 'UTC'… 在我引用的返回行中产生 2014-05-01 23:05:00+08
  • @JFSebastian:嗯,我现在明白我没有得到 UTC 值,在我之前的评论中使用 SELECT,而只是要求将无时区时间戳视为 UTC (在我的本地时区显示之前)。 在表中有带时区的时间戳解决了这个问题,你关注时区是对的。

标签: python postgresql datetime timestamp psycopg2


【解决方案1】:

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

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

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

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

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

  • 当进行 比较 像“timestamp without time zone” with time zone”时,我不能在文档中找到 PostgreSQL 的功能。但是,在问题中观察到的情况与首先以相同方式删除时区,并比较没有时区的时间戳的想法是一致的。我不应该对结果感到惊讶:在中国 (UTC+8),迟到的时间“15:00”确实比世界标准时间 13:00 早。关键是要知道显示(和存储)的时间是当地时区。

我从中得到的启示是:带有和不带时区的时间戳之间的转换更好地处理明确

【讨论】:

【解决方案2】:

指定显示时间的时区。如果 start_timeend_time 是时间戳 without 时区正如您的输出所示,那么您还需要告诉 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

【讨论】:

  • 使用where end_time &lt; '2014-05-01T13:00:00+00:00'::timestamptz;,这会产生一个结束时间为2014-05-01 23:05:00+08 的行,因此在世界标准时间15:05,尽管限制是世界标准时间13:00。我是否正确理解问题仍然存在?
  • 你说得对,这是一个时区问题。但是,此解决方案不起作用,但在时区 'UTC' 进行双重测试也会产生一致(即不令人惊讶)的结果。不过,我只是明白时间是错误的:原来的时间是不是 UTC,所以第一个at time zone 'UTC' 创建的时间大多毫无意义……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 2012-05-27
  • 2012-09-26
相关资源
最近更新 更多