gpt4 book ai didi

ruby-on-rails - Rails 和 PostgreSQL 中的时区和夏令时

转载 作者:行者123 更新时间:2023-11-29 12:34:02 25 4
gpt4 key购买 nike

背景

带有默认 created_at 列的文章模型

Rails config.time_zone = '华沙'

我有一篇文章,created_at = 本地时间 2012-08-19 00:15(UTC 时间为 2012-08-18 22:15)。

目标

接收 2012 年 8 月 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 中运行相同的查询,它会返回一篇文章……这让我很困惑。

问题

我做错了什么以及如何解决?

最佳答案

Goal: To receive all articles created in 2012-08-19 (in local time).

'+01:00' (就像您使用的那样)是一个固定时间偏移,不能将 DST(夏令时)考虑在内。为此使用时区名称(不是缩写)。这些在 PostgreSQL 中可用:

SELECT * FROM pg_timezone_names;

对于华沙,这应该是 'Europe/Warsaw' .系统从其存储的信息中获知夏令时的范围,并应用相应的时间偏移量。


此外,您的查询可以得到简化。

作为created_attimestamp [without time zone] ,保存的值反射(reflect)了创建行时服务器的本地时间(在内部保存为 UTC 时间戳)。

基本上只有两种可能性,具体取决于您客户所在的时区。

  1. 您的阅读客户端以相同设置运行 timezone 作为写作客户:只是投到日期。

    SELECT *
    FROM articles
    WHERE created_at::date = '2012-08-19';
  2. 您的阅读客户端以不同的设置运行 timezone 比写作客户端:添加AT TIME ZONE '<tz name of *writing* client here> '.例如,如果那是 Europe/Warsaw ,它看起来像:

    ...
    WHERE (created_at AT TIME ZONE 'Europe/Warsaw')::date = '2012-08-19';

AT TIME ZONE的双重应用就像您在发布的答案中一样,不需要

注意时区名称 而不是缩写。见:

如果您的应用程序跨越多个时区..

.. 将列默认设置为 created_atnow() AT TIME ZONE 'UTC' - 或其他一些时区,重点是:在任何地方都使用相同的时区。

.. 或者,最好,切换到timestamptz (timestamp with time zone)。

关于ruby-on-rails - Rails 和 PostgreSQL 中的时区和夏令时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12022814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com