将Rails DateTime四舍五入到最近的15分钟间隔

时间:2013-09-12 21:54:50

标签: ruby-on-rails ruby datetime ruby-on-rails-3.2 ruby-on-rails-4

我需要将DateTimeTime四舍五入到最近的15分钟。我的想法是将秒和毫秒归零(那些存在于DateTimeTime?)甚至可能是纳秒?然后将分钟数除以15,然后将结果乘以15并将其设置为分钟:

# zero out the seconds
time -= time.sec.seconds
# zero out the milliseconds (does that exist?)
# zero out the nanoseconds (less likely this exists)

minutes_should_be = (time.min / 15.to_f).round * 15
time += (minutes_should_be - time.min).minutes

所以我想我的问题是,如果有更好的方法可以做到这一点,并且DateTimeTime中是否存在毫秒和纳秒?有纳秒的nsec方法,但我认为这是自纪元以来的总纳秒。

3 个答案:

答案 0 :(得分:6)

以下应该可以解决问题:

##
# rounds a Time or DateTime to the neares 15 minutes
def round_to_15_minutes(t)
  rounded = Time.at((t.to_time.to_i / 900.0).round * 900)
  t.is_a?(DateTime) ? rounded.to_datetime : rounded
end

该函数将输入转换为Time对象,可以使用to_i将其转换为自纪元以来的秒数(这会自动剥离纳米/毫秒)。然后我们将15分钟(900秒)除以得到的浮子。这会自动将时间四舍五入到最近的15分钟。现在,我们只需将结果乘以15分钟,然后再将其转换为(日期)时间。

示例值:

round_to_15_minutes Time.new(2013, 9, 13, 0, 7, 0, "+02:00")
#=> 2013-09-13 00:00:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 8, 0, "+02:00")
#=> 2013-09-13 00:15:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 22, 29, "+02:00")
#=> 2013-09-13 00:15:00 +0200
round_to_15_minutes Time.new(2013, 9, 13, 0, 22, 30, "+02:00")
#=> 2013-09-13 00:30:00 +0200
round_to_15_minutes DateTime.now
#=> #<DateTime: 2013-09-13T01:00:00+02:00 ((2456548j,82800s,0n),+7200s,2299161j)>

答案 1 :(得分:2)

我认为这会起作用

def nearest15 minutes
  ((minutes / 60.0 * 4).round / 4.0 * 60).to_i
end

这个想法是

  • 按小时(小数)计算您的会议记录
  • 四舍五入到最近的一个季度
  • 转换回分钟

一些示例输出

10.times do
  n = [*1..200].sample
  puts "%d => %d" % [n, nearest15(n)]
end

输出

85 => 90
179 => 180
54 => 60
137 => 135
104 => 105
55 => 60
183 => 180
184 => 180
46 => 45
92 => 90

答案 2 :(得分:2)

DateTime的通用舍入解决方案,基于Tessi的回答:

class DateTime

  def round(granularity=1.hour)
    Time.at((self.to_time.to_i/granularity).round * granularity).to_datetime
  end

end

使用示例:

DateTime.now.round 15.minutes
> Fri, 15 May 2015 11:15:00 +0100