generate_series
您正在使用的版本使用的是时间戳,而不是日期。因此,您的'2012-10-14'
andcurrent_date
正在转换为timestamp with time zone
s 并且generate_series
正在生成一组timestamp with time zone
s;比较这些:
=> 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。
如果您手动指定当前日期并明确使用timestamp
s:
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"}]
顺便说一句,我讨厌时区,讨厌并鄙视它们。