4

我需要将 aDateTime和 a舍Time入到最接近的 15 分钟间隔。我的想法是将秒和毫秒(它们是否存在于 aDateTimeTime?)甚至纳秒中归零?然后将分钟数除以 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

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

4

3 回答 3

7

以下应该可以解决问题:

##
# 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)>
于 2013-09-12T22:42:37.220 回答
3

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

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
于 2015-05-15T10:23:19.087 回答
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
于 2013-09-12T22:00:26.560 回答