Ruby 将秒(浮动)转换为小时/秒/分钟

Ruby 将秒(浮动)转换为小时/秒/分钟,ruby,time,Ruby,Time,我有一个表示秒的浮点数。所以,我可以有38.93秒。如果可能的话,我在寻找“最红”的方式来计算小时数,如果不可能计算小时数,则是分钟数,如果不可能计算分钟数,则是秒数。当我说可能时,我的意思是: 如果少于3600秒,则为分或秒。如果少于60秒,则为秒 现在我做了几次if,看看应该是什么,但我想可能必须有一个更干净的方法 if input > 3600 return input/3600, 'hours' elseif input < 3600 && input

我有一个表示秒的浮点数。所以,我可以有38.93秒。如果可能的话,我在寻找“最红”的方式来计算小时数,如果不可能计算小时数,则是分钟数,如果不可能计算分钟数,则是秒数。当我说可能时,我的意思是:

如果少于3600秒,则为分或秒。如果少于60秒,则为秒

现在我做了几次if,看看应该是什么,但我想可能必须有一个更干净的方法

if input > 3600
   return input/3600, 'hours'
elseif input < 3600 && input > 60
   return input/60, 'minutes'
else 
   return input, 'seconds'
如果输入>3600
返回输入/3600,“小时”
elseif输入<3600&&input>60
返回输入/60,“分钟”
其他的
返回输入,“秒”
谢谢

输出:

输出:


IMHO带有范围的案例陈述会更清晰一些:

def some_method_name(input)
  case input
  when 0...60
    input, 'seconds'
  when 60...3600
    input/60, 'minutes'
  else
    input/3600, 'hours'
  end
end
另一种方法是先提取小时、分钟和秒:

def some_method_name(input)
  hours, seconds = input.divmod(3600)
  minutes, seconds = seconds.divmod(60)

  if hours > 0
    hours, 'hours'
  elsif minutes > 0
    minutes, 'minutes'
  else
    seconds, 'seconds'
  end
end

在Rails中,您当然会使用内置组件。

IMHO带有范围的case语句会更干净一些:

def some_method_name(input)
  case input
  when 0...60
    input, 'seconds'
  when 60...3600
    input/60, 'minutes'
  else
    input/3600, 'hours'
  end
end
另一种方法是先提取小时、分钟和秒:

def some_method_name(input)
  hours, seconds = input.divmod(3600)
  minutes, seconds = seconds.divmod(60)

  if hours > 0
    hours, 'hours'
  elsif minutes > 0
    minutes, 'minutes'
  else
    seconds, 'seconds'
  end
end

在Rails中,您当然会使用内置函数。

这种方法的优点是能够灵活地指定所需的单位间隔。如果你愿意的话,可以很容易地加上几周、大约几个月、几年。它还修复了奇异值的复数化

TimeInt = Struct.new :name, :secs
INTERVALS = [ TimeInt[:days, 60*60*24], TimeInt[:hours, 60*60],
              TimeInt[:minutes, 60], TimeInt[:seconds, 1] ]

def time_with_adaptive_units(secs)
  ti = INTERVALS.find { |ti| secs >= ti.secs } || INTERVALS.last
  val, name = (secs.to_f/ti.secs).round, ti.name.to_s
  name.sub!(/s$/,'') if val == 1
  "#{val} #{name}"
end

[5] pry(main)> time_with_adaptive_units(1)
=> "1 second"
[6] pry(main)> time_with_adaptive_units(45)
=> "45 seconds"
[7] pry(main)> time_with_adaptive_units(450)
=> "7 minutes"
[8] pry(main)> time_with_adaptive_units(4500)
=> "1 hour"
[9] pry(main)> time_with_adaptive_units(45000)
=> "12 hours"
[10] pry(main)> time_with_adaptive_units(450000)
=> "5 days"

这种方法的优点是能够灵活地指定所需的单位间隔。如果你愿意的话,可以很容易地加上几周、大约几个月、几年。它还修复了奇异值的复数化

TimeInt = Struct.new :name, :secs
INTERVALS = [ TimeInt[:days, 60*60*24], TimeInt[:hours, 60*60],
              TimeInt[:minutes, 60], TimeInt[:seconds, 1] ]

def time_with_adaptive_units(secs)
  ti = INTERVALS.find { |ti| secs >= ti.secs } || INTERVALS.last
  val, name = (secs.to_f/ti.secs).round, ti.name.to_s
  name.sub!(/s$/,'') if val == 1
  "#{val} #{name}"
end

[5] pry(main)> time_with_adaptive_units(1)
=> "1 second"
[6] pry(main)> time_with_adaptive_units(45)
=> "45 seconds"
[7] pry(main)> time_with_adaptive_units(450)
=> "7 minutes"
[8] pry(main)> time_with_adaptive_units(4500)
=> "1 hour"
[9] pry(main)> time_with_adaptive_units(45000)
=> "12 hours"
[10] pry(main)> time_with_adaptive_units(450000)
=> "5 days"

我能想到的是:

total_seconds = 23456
intervals = [3600, 60, 1].inject({rem: total_seconds, parts:[]}) do |memo, factor|
    count = (memo[:rem] / factor).floor
    memo[:rem] = memo[:rem] - (count * factor)
    memo[:parts] << count
    memo
end

你还可以看到,如果你想把它扩展到几天、几周、几个月、几年、几十年和几个世纪,这是很简单的:D

我可以想到:

total_seconds = 23456
intervals = [3600, 60, 1].inject({rem: total_seconds, parts:[]}) do |memo, factor|
    count = (memo[:rem] / factor).floor
    memo[:rem] = memo[:rem] - (count * factor)
    memo[:parts] << count
    memo
end

你也可以看到,如果你想,把它扩展到几天、几周、几个月、几年、几十年和几个世纪是很简单的:D

38.93不是一个Fixnum。大卫,对不起,我是说Float38.93不是一个Fixnum。大卫,对不起,我是说FloatThis看起来不错,但我只想返回“小时”或“分钟”或“秒”,而不是这三个,但我只想返回“小时”或“分钟”或“秒”,而不是三个,这很好!我应该在哪里定义结构呢?使用Rails,我想将该方法放在ApplicationHelper中。如果在方法本身内部定义结构,则会出现“动态常数赋值”错误。@HommerSmith如果您只在方法定义上方使用它,我会在方法定义的正上方定义结构和间隔。这只是一个小伙伴,使间隔数据自标记。这是很好的!我应该在哪里定义结构呢?使用Rails,我想将该方法放在ApplicationHelper中。如果在方法本身内部定义结构,则会出现“动态常数赋值”错误。@HommerSmith如果您只在方法定义上方使用它,我会在方法定义的正上方定义结构和间隔。这只是一个小伙伴,使间隔数据自标记。