如何在前一天下午2:00用Ruby定义?

mar*_*man 1 ruby activerecord ruby-on-rails

我需要从昨天下午2点到现在搜索事件,我正在尝试这样做

events.where("DATE(created_at) >= ? and DATE(created_at) <=", (1.day.ago + 14.hours).strftime('%Y-%m-%d %H:%M:'), Time.now.strftime('%Y-%m-%d %H:%M:') )
Run Code Online (Sandbox Code Playgroud)

但它显示为空...但是当我从格式化文本中删除"%H:%M:"时,我也得到了它们.

tad*_*man 6

首先,您需要处理"昨天下午2点"的内容,我将其翻译为:

DateTime.now.yesterday.beginning_of_day.change(:hour => 14)
Run Code Online (Sandbox Code Playgroud)

这里发布的许多解决方案建议在昨天开始增加14个小时,但这是错误的.记住夏令时!更安全的是简单地将小时改为适当的值.

一天不会有24小时.有23,24和25取决于它是什么日子.为了证明这一点,请查看DST过渡期:

Time.zone = 'EST5EDT'
DateTime.parse('2012-03-12 12:34:56 -0500').to_time_in_current_zone.yesterday.beginning_of_day + 14.hours
# => Sun, 11 Mar 2012 15:00:00 EDT -04:00
Run Code Online (Sandbox Code Playgroud)

那是下午3点,因为凌晨1点到凌晨2点没有发生.使用change你应该总是得到正确的结果:

DateTime.parse('2012-03-12 12:34:56 -0500').to_time_in_current_zone.yesterday.beginning_of_day.change(:hour => 14)
# => Sun, 11 Mar 2012 14:00:00 EDT -04:00 
Run Code Online (Sandbox Code Playgroud)

通常你也可以使用BETWEEN运算符来简化你的日期计算,但是在你的情况下,因为你在那个时间点和现在之间取得,假设你将来没有事件你可以省略一个边界.此外,ActiveRecord应该在进行查询时正确处理格式化DateTime值,因此strftime调用通常会适得其反,因为您可能很容易弄错.

events.where("DATE(created_at) >= ?", DateTime.now.yesterday.beginning_of_day.change(:hour => 14))
Run Code Online (Sandbox Code Playgroud)

如果您因任何原因必须处理未来事件:

events.where("DATE(created_at) BETWEEN ? AND ?", DateTime.now.yesterday.beginning_of_day.change(:hour => 14), DateTime.now)
Run Code Online (Sandbox Code Playgroud)

请记住,以UTC格式存储数据库时间并在执行查询时从本地时间转换为UTC通常是有利的.如果您需要同时处理多个时区,则在数据库中存储时区污染值会产生各种麻烦.