带有默认created_at
列的商品模型
Rails config.time_zone = 'Warsaw'
我有一篇有关created_at =当地时间2012-08-19 00:15(UTC中的2012-08-18 22:15的文章。
[接收所有在2012-08-19(当地时间)创建的文章。
Article.where(
"date_trunc('day', created_at AT TIME ZONE '#{Time.zone.formatted_offset}')
= '#{Date.civil(2012, 8, 19)}'"
)
哪个生成SQL:
SELECT "articles".* FROM "articles"
WHERE (date_trunc('day', created_at AT TIME ZONE '+01:00') = '2012-08-19')
并返回一个空集。但是,如果我在psql中运行相同的查询,它将返回一条文章...使我感到困惑。
我在做什么错以及如何解决?
目标:接收2012年8月19日(当地时间)创建的所有文章。
'+01:00'
(就像您使用它)是一个fixed时间偏移,并且不能考虑DST(夏令时)。为此使用时区name(不是缩写)。这些在PostgreSQL中可用:
SELECT * FROM pg_timezone_names;
对于华沙,这应该是'Europe/Warsaw'
。系统从其存储的信息中了解DST的范围,并应用相应的时间偏移。
此外,您的查询可以简化。
由于'Europe/Warsaw'
是created_at
,所以保存的值反映了创建行时服务器的本地时间(内部保存为UTC时间戳)。
基本上只有两种可能,具体取决于客户所在的时区。
您的阅读客户端使用timestamp [without time zone]
的相同设置作为书写客户端:只是强制转换为最新。
timezone
您的阅读客户端以timezone
的不同设置运行,而不是书写客户端:添加SELECT *
FROM articles
WHERE created_at::date = '2012-08-19';
'。例如,如果是timezone
,则看起来像:
timezone
AT TIME ZONE '<tz name of *writing* client here>
的双重申请,就像您在已发布的答案中一样,应该不是。
注意时区name,而不是缩写。参见:
Europe/Warsaw
如果您的应用程序跨越多个时区..
..将...
WHERE (created_at AT TIME ZONE 'Europe/Warsaw')::date = '2012-08-19';
的列默认设置为AT TIME ZONE
-或其他时区,重点是:在各处使用相同的值。
..或最好,切换到Time zone names with identical properties yield different result when applied to timestamp(created_at
)。
now() AT TIME ZONE 'UTC'
帮助了。我必须运行以下查询:
timestamptz
此问题将需要对created_at列的确切定义(确切的数据类型是什么?]
Rails总是将created_at列创建为没有时区的时间戳。因此,我必须使第一个timestamp with time zone
表示该时间戳记为UTC的dbms,第二个要显示CEST区域的日期的时间。