5

在 psql 中运行以下查询时,我得到 7 个结果:

SELECT generate_series('2012-10-14', CURRENT_DATE, interval '1 day'); # 7

但是,当我在我的 rails 应用程序中运行完全相同的查询时,我得到 8 个结果:

result = ActiveRecord::Base.connection.execute "SELECT generate_series('2012-10-14', CURRENT_DATE, interval '1 day');"
puts result.count # 8

似乎这与时区有关,但我不知道问题可能是什么。我的 application.rb 中有以下内容

config.time_zone = 'Eastern Time (US & Canada)'

这与我在 postgresql.conf 中的时区设置相同

我对为什么我的 rails 应用程序为我的结果增加了一天感到困惑。谁能提供一些见解?

这似乎只发生在一天结束时(晚上 8 点之后),所以这就是让我认为这是带有时区偏移的东西。

4

1 回答 1

9

generate_series您正在使用的版本使用的是时间戳,而不是日期。因此,您的'2012-10-14'andcurrent_date正在转换为timestamp with time zones 并且generate_series正在生成一组timestamp with time zones;比较这些:

=> select generate_series('2012-10-14', current_date, '1 day');
    generate_series     
------------------------
 2012-10-14 00:00:00-07
 2012-10-15 00:00:00-07
 2012-10-16 00:00:00-07
 2012-10-17 00:00:00-07
 2012-10-18 00:00:00-07
 2012-10-19 00:00:00-07
 2012-10-20 00:00:00-07
(7 rows)

=> select generate_series('2012-10-14', current_date::timestamp, '1 day');
   generate_series   
---------------------
 2012-10-14 00:00:00
 2012-10-15 00:00:00
 2012-10-16 00:00:00
 2012-10-17 00:00:00
 2012-10-18 00:00:00
 2012-10-19 00:00:00
 2012-10-20 00:00:00
(7 rows)

第一个有时区,第二个没有。

但是,current_date始终会转换为应用了数据库会话的时区调整的时间戳。Rails 会话将以 UTC 与数据库对话,您的psql会话可能使用 ET。

如果您手动指定当前日期并明确使用timestamps:

select generate_series('2012-10-14'::timestamp, '2012-10-20'::timestamp, '1 day')

那么您将在两者中得到相同的七个结果,因为没有时区可以使事情变得一团糟。

忽略时区的最简单方法是使用整数版本,generate_series并且将整数添加到日期会将整数视为天数:

select '2012-10-14'::date + generate_series(0, 6)

这将为您提供相同的 7 天,而不受时区干扰。您仍然可以current_date通过注意两个日期之间的差异是它们之间的天数(整数)来使用(没有时区,因为 SQL 日期没有时区):

=> select '2012-10-14'::date + generate_series(0, current_date - '2012-10-14');
  ?column?  
------------
 2012-10-14
 2012-10-15
 2012-10-16
 2012-10-17
 2012-10-18
 2012-10-19
 2012-10-20
(7 rows)

并来自 Rails:

> pp ActiveRecord::Base.connection.execute("select '2012-10-14'::date + generate_series(0, 6)").to_a
[{"?column?"=>"2012-10-14"},
 {"?column?"=>"2012-10-15"},
 {"?column?"=>"2012-10-16"},
 {"?column?"=>"2012-10-17"},
 {"?column?"=>"2012-10-18"},
 {"?column?"=>"2012-10-19"},
 {"?column?"=>"2012-10-20"}]

顺便说一句,我讨厌时区,讨厌并鄙视它们。

于 2012-10-21T02:05:50.893 回答