Rails/Postgresql SQL差异w /日期

Kyl*_*cot 5 postgresql ruby-on-rails date ruby-on-rails-3

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

SELECT generate_series('2012-10-14', CURRENT_DATE, interval '1 day'); # 7
Run Code Online (Sandbox Code Playgroud)

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

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

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

config.time_zone = 'Eastern Time (US & Canada)'
Run Code Online (Sandbox Code Playgroud)

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

我很困惑为什么我的rails应用程序为我的结果添加了额外的一天.谁能提供一些见解?

这似乎只发生在一天结束时(晚上8点之后)所以这就是让我认为这是时区偏移的原因.

mu *_*ort 9

generate_series您正在使用的版本是使用时间戳,而不是日期.所以你的'2012-10-14'并且current_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)
Run Code Online (Sandbox Code Playgroud)

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

但是,current_date始终会转换为时间戳,并应用数据库会话的时区调整.Rails会话将以UTC格式与数据库通信,您的psql会话可能正在使用ET.

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

select generate_series('2012-10-14'::timestamp, '2012-10-20'::timestamp, '1 day')
Run Code Online (Sandbox Code Playgroud)

然后你会得到相同的七个结果,因为没有时间区域可以制造混乱的东西.

忽略时区的最简单方法是使用整数版本generate_series以及向日期添加整数这一事实将整数视为天数:

select '2012-10-14'::date + generate_series(0, 6)
Run Code Online (Sandbox Code Playgroud)

这将给你七天没有时区干扰.您仍然可以使用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)
Run Code Online (Sandbox Code Playgroud)

从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"}]
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我讨厌时区,讨厌和鄙视他们.

  • +1优秀的解释.顺便说一下,我为DST(夏令时)的愚蠢概念保留了我的仇恨*,它既没有节省任何日光也没有任何意义.通过引起混乱,在世界各地浪费了很多时间.DST应该从存在中移除,永远不会再被提及. (2认同)
  • @ErwinBrandstetter:我不能在一个不鼓励咒骂的公共论坛上谈论DST,我就是做不到. (2认同)