怎么把270921sec转换成天+小时+分钟+秒?(红宝石)


68

我有几秒钟。假设是270921。我如何显示该数字以表示是xx天,yy小时,zz分钟,ww秒?

Answers:


160

可以使用divmod以下命令非常简洁地完成:

t = 270921
mm, ss = t.divmod(60)            #=> [4515, 21]
hh, mm = mm.divmod(60)           #=> [75, 15]
dd, hh = hh.divmod(24)           #=> [3, 3]
puts "%d days, %d hours, %d minutes and %d seconds" % [dd, hh, mm, ss]
#=> 3 days, 3 hours, 15 minutes and 21 seconds

您可能可以通过利用collect或进行创意来进一步干燥它inject,但是当核心逻辑是三行时,这可能会显得过分。


@迈克·伍德豪斯:那是我一直在寻找的东西。谢谢。
Radek

+1,如果我需要显示直到90分钟的秒数该怎么办,例如我正在跟踪游戏。它应该显示类似90:54的内容。谢谢!
uday 2012年

@uDaY可以看到我的增强答案。我不太了解您要做什么,但也许会有所帮助。
开尔文

1
为此,我必须为其创建一个简洁的小方法:def seconds_to_dhms(seconds); [60,60,24] .map {| dm | 秒,t = seconds.divmod(dm); t} .reverse.unshift秒;结束
乍得M

使用此代码或Benchmark类进行基准测试是否更好(即仅计算完成某项工作所需的时间)?
2015年

13

我希望有比使用divmod更简单的方法,但这是我发现的最干燥和可重用的方法:

def seconds_to_units(seconds)
  '%d days, %d hours, %d minutes, %d seconds' %
    # the .reverse lets us put the larger units first for readability
    [24,60,60].reverse.inject([seconds]) {|result, unitsize|
      result[0,0] = result.shift.divmod(unitsize)
      result
    }
end

通过更改格式字符串和第一个内联数组(即[24,60,60]),可以轻松调整该方法。

增强版

class TieredUnitFormatter
  # if you set this, '%d' must appear as many times as there are units
  attr_accessor :format_string

  def initialize(unit_names=%w(days hours minutes seconds), conversion_factors=[24, 60, 60])
    @unit_names = unit_names
    @factors = conversion_factors

    @format_string = unit_names.map {|name| "%d #{name}" }.join(', ')
    # the .reverse helps us iterate more effectively
    @reversed_factors = @factors.reverse
  end

  # e.g. seconds
  def format(smallest_unit_amount)
    parts = split(smallest_unit_amount)
    @format_string % parts
  end

  def split(smallest_unit_amount)
    # go from smallest to largest unit
    @reversed_factors.inject([smallest_unit_amount]) {|result, unitsize|
      # Remove the most significant item (left side), convert it, then
      # add the 2-element array to the left side of the result.
      result[0,0] = result.shift.divmod(unitsize)
      result
    }
  end
end

例子:

fmt = TieredUnitFormatter.new
fmt.format(270921)  # => "3 days, 3 hours, 15 minutes, 21 seconds"

fmt = TieredUnitFormatter.new(%w(minutes seconds), [60])
fmt.format(5454)  # => "90 minutes, 54 seconds"
fmt.format_string = '%d:%d'
fmt.format(5454)  # => "90:54"

请注意,format_string这不会让您更改零件的顺序(它始终是最高有效值或最低有效值)。为了获得更精细的控制,您可以split自己使用和操纵这些值。


11

需要休息一下。打高尔夫球:

s = 270921
dhms = [60,60,24].reduce([s]) { |m,o| m.unshift(m.shift.divmod(o)).flatten }
# => [3, 3, 15, 21]

您只是从此答案中复制而来。
Iulian Onofrei


9

如果您使用的是Rails,则不需要精度即可采用一种简单的方法:

time_ago_in_words 270921.seconds.from_now
# => 3 days

4

您可以使用针对此问题找到的最简单的方法:

  def formatted_duration total_seconds
    hours = total_seconds / (60 * 60)
    minutes = (total_seconds / 60) % 60
    seconds = total_seconds % 60
    "#{ hours } h #{ minutes } m #{ seconds } s"
  end

您始终可以根据需要调整返回值。

2.2.2 :062 > formatted_duration 3661
 => "1 h 1 m 1 s"

2

我刚开始写红宝石。我猜这仅适用于1.9.3

def dateBeautify(t)

    cute_date=Array.new
    tables=[ ["day", 24*60*60], ["hour", 60*60], ["minute", 60], ["sec", 1] ]

    tables.each do |unit, value|
        o = t.divmod(value)
        p_unit = o[0] > 1 ? unit.pluralize : unit
        cute_date.push("#{o[0]} #{unit}") unless o[0] == 0
        t = o[1]
    end
    return cute_date.join(', ')

end

2

我修改了@Mike给出的答案,以根据结果的大小添加动态格式

      def formatted_duration(total_seconds)
        dhms = [60, 60, 24].reduce([total_seconds]) { |m,o| m.unshift(m.shift.divmod(o)).flatten }

        return "%d days %d hours %d minutes %d seconds" % dhms unless dhms[0].zero?
        return "%d hours %d minutes %d seconds" % dhms[1..3] unless dhms[1].zero?
        return "%d minutes %d seconds" % dhms[2..3] unless dhms[2].zero?
        "%d seconds" % dhms[3]
      end

0

天数= 270921/86400(天中的秒数)= 3天,这是绝对值

剩余秒数(t)= 270921-3 * 86400 = 11721

3.to_s + Time.at(t).utc.strftime(":%H:%M:%S")

会产生类似3:03:15:21的内容

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.