如何以毫秒为单位显示持续时间作为格式正确的字符串?

时间:2017-04-17 21:56:39

标签: ruby string time format

我正在使用Ruby 2.4。我想将毫秒转换为可读的小时,分​​钟和秒格式。所以我有这个方法

  def time_as_str(time_in_ms)
    regex = /^(0*:?)*0*/
    Time.at(time_in_ms.to_f/1000).utc.strftime("%H:%M:%S.%1N").sub!(regex, '')
  end

问题是,如果我的值以毫秒为单位或更大,则此函数不会显示正确的值。例如,如果我通过

2.4.0 :009 > TimeFormattingHelper.time_as_str(86400000)
 => ".0"

86400000是一天(毫秒)(除非我算错了)。所以我希望价值是“24:00:00”。如何更正以上内容以正确显示格式化的时间?

2 个答案:

答案 0 :(得分:1)

def time_as_str(ms)
  secs, ms    =   ms.divmod(1000)
  mins, secs  = secs.divmod(60)
  hours, mins = mins.divmod(60)
  s = "%d.%d.%d.%s" % [hours, mins, secs, ms.zero? ? "0" : ms.to_s.sub(/0*\z/,'')]
  if hours > 0
    s
  elsif mins > 0
    s[2..-1]
  else
    s[4..-1]   
  end      
end

time_as_str(86_400_000)    #=> "24.0.0.0"
time_as_str(0)             #=> "0.0"
time_as_str(499)           #=> "0.499"
time_as_str(60_280)        #=> "1.0.28"
time_as_str(360_000)       #=> "6.0.0"
time_as_str(1_000_000_200) #=> "277.46.40.2"

请参阅Integer#divmod,这是一种经常被忽视的方法。

假设

ms = 2_045_670

然后

secs, ms    =   ms.divmod(1000)
  #=> [2045, 670] (secs #=> 2045, ms #=> 670)
mins, secs  = secs.divmod(60)
  #=> [34, 5]
hours, mins = mins.divmod(60)
  #=> [0, 34]
ms = ms.zero? ? "0" : ms.to_s.sub(/0*\z/,'')
  #=> "67" (truncate)
s = "%d.%d.%d.%s" % [hours, mins, secs, ms]
  #=> "0.34.5.67"
if hours > 0   # false
  "0.34.5.67" 
elsif mins > 0 # true
  "34.5.67"
else           # not evaluated
  "5.67" 
end
  #=> "34.5.67"

答案 1 :(得分:-1)

一些基本信息:

  • 秒= 1000毫秒
  • 一分钟= 1000×60毫秒
  • 一小时= 1000×60×60毫秒

现在,您可以尝试以下方法:

def get_duration_hrs_and_mins(duration)
  duration = duration.to_i

  h = duration / (1000 * 60 * 60)
  m = duration / (1000 * 60) % 60
  s = duration / (1000.to_f) % 60

  h = zero_to_nil(h)
  m = zero_to_nil(m) if h.nil?

  arr = [h, m, s].map { |e| format_val(e) }

  arr.compact.join(':')
end

def format_val(e)
  case
  when e.nil?
    nil
  when e.zero?
    '00'
  when e.round(0) == e
    sprintf("%2d", e)
  else
    e.round(3)
  end
end

def zero_to_nil(val)
  val.zero? ? nil : val
end

rails控制台的一些输出:

puts get_duration_hrs_and_mins(86400000)
# => 24:00:00
puts get_duration_hrs_and_mins(150400)
# => 2:30.4
puts get_duration_hrs_and_mins(150401)
# => 2:30.401
puts get_duration_hrs_and_mins(1500)
# => 1.5
puts get_duration_hrs_and_mins(864000)
# => 14:24