在 Rails 3 或 Ruby 中将持续时间转换为小时:分钟:秒(或类似的)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4175733/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:38:06  来源:igfitidea点击:

Convert duration to hours:minutes:seconds (or similar) in Rails 3 or Ruby

ruby-on-railsrubydatetimeruby-on-rails-3

提问by cydonia

I have a feeling there is a simple/built-in way to do this but I can't find it.

我觉得有一种简单/内置的方法可以做到这一点,但我找不到。

I have a duration (in seconds) in an integer and I want to display it in a friendly format.

我有一个整数的持续时间(以秒为单位),我想以友好的格式显示它。

e.g. 3600 would be displayed as "01:00:00" or "1 hour" or something.

例如,3600 将显示为“01:00:00”或“1 小时”或其他内容。

I can do it with time_ago_in_words(Time.zone.now+3600)but that feels like a bit of a hack, there is no reason to add/subtract from the current time just to format this value. Is there a duration_in_words()or something?

我可以做到,time_ago_in_words(Time.zone.now+3600)但这感觉有点像黑客,没有理由仅仅为了格式化这个值而从当前时间添加/减去。有没有duration_in_words()什么的?

Thanks

谢谢

回答by Lev Lukomsky

Summing up:

加起来:

assuming that total_seconds = 3600

假如说 total_seconds = 3600

Option 1:

选项1:

distance_of_time_in_words(total_seconds) #=> "about 1 hour"

Option 2:

选项 2:

Time.at(total_seconds).utc.strftime("%H:%M:%S") #=> "01:00:00"

Option 3:

选项 3:

seconds = total_seconds % 60
minutes = (total_seconds / 60) % 60
hours = total_seconds / (60 * 60)

format("%02d:%02d:%02d", hours, minutes, seconds) #=> "01:00:00"

use Option1if you want words, Option2if you want H:M:S format, Option3if you want H:M:S format and there can be more than 24 hours

使用选项1,如果你想的话,1选项,如果你想H:M:S格式,选项3,如果你想H:M:S格式,可以有24小时以上

回答by IAmNaN

Ruby's string %operator is too unappreciated and oft forgotten.

Ruby 的字符串%运算符太不受欢迎,而且经常被遗忘。

"%02d:%02d:%02d:%02d" % [t/86400, t/3600%24, t/60%60, t%60]

Given tis a duration in seconds, this emits a zero-padded colon-separated string including days. Example:

鉴于t是以秒为单位的持续时间,这会发出一个以零填充的冒号分隔的字符串,包括天数。例子:

t = 123456
"%02d:%02d:%02d:%02d" % [t/86400, t/3600%24, t/60%60, t%60]
=> "01:10:17:36"

Lovely.

迷人的。

回答by Cristobal Viedma

I guess you could do also something like:

我想你也可以这样做:

(Time.mktime(0)+3600).strftime("%H:%M:%S")

To format it as you wish.

按照您的意愿对其进行格式化。

BTW, originally I thought of using Time.at() but seems that EPOCH time on my Ubuntu is Thu Jan 01 01:00:00 +0100 1970 and not 00:00:00 hours as I expected, and therefore if I do:

顺便说一句,最初我想使用 Time.at() 但似乎我的 Ubuntu 上的 EPOCH 时间是 Thu Jan 01 01:00:00 +0100 1970 而不是我预期的 00:00:00 小时,因此如果我这样做:

Time.at(3600).strftime("%H:%M:%S")

Gives me 1 hour more than wanted.

给了我超过想要的 1 小时。

回答by Sheharyar

I use this to show time durations in my Rails Project:

我用它来显示我的 Rails 项目中的持续时间:

  1. Add a custom method to the Integerclass. You can create a new file called pretty_duration.rbin the initializersfolder:

    class Integer
        def pretty_duration
            parse_string = 
                if self < 3600
                    '%M:%S'
                else
                    '%H:%M:%S'
                end
    
            Time.at(self).utc.strftime(parse_string)
        end
    end
    
  2. Call seconds.pretty_durationanywhere in your project:

    275.pretty_duration     # => "04:35"
    9823.pretty_duration    # => "02:43:43"
    
  1. Integer类添加自定义方法。您可以pretty_duration.rbinitializers文件夹中创建一个名为的新文件:

    class Integer
        def pretty_duration
            parse_string = 
                if self < 3600
                    '%M:%S'
                else
                    '%H:%M:%S'
                end
    
            Time.at(self).utc.strftime(parse_string)
        end
    end
    
  2. seconds.pretty_duration在项目中的任何地方调用:

    275.pretty_duration     # => "04:35"
    9823.pretty_duration    # => "02:43:43"
    


This answer builds up on Lev Lukomsky's Code

这个答案建立在Lev Lukomsky 的代码之上

回答by Brent Royal-Gordon

This one uses the obscure divmodmethod to divide and modulo at the same time, so it handles Floatseconds properly:

这个使用了晦涩的divmod方法同时进行了除法和取模,所以它Float正确地处理了秒:

def duration(seconds)
  minutes, seconds = seconds.divmod(60)
  hours, minutes = minutes.divmod(60)
  days, hours = hours.divmod(24)

  "#{days.to_s.rjust(3)}d #{hours.to_s.rjust(2)}h #{minutes.to_s.rjust(2)}m #{seconds}s"
end

回答by Xiao Bin

Be careful with the duration longer than one day.

超过一天的持续时间要小心。

(timing/3600).to_i.to_s.rjust(2,'0') + ":"+Time.at(timing).utc.strftime("%M:%S")

回答by Igor Springer

Using Time.utc.strftimeworks only for values when total number of hours is less then 24:

使用Time.utc.strftime仅适用于总小时数小于 24 的值

2.2.2 :004 > Time.at(60 * 60).utc.strftime('%H h %M m')
=> "01 h 00 m"

For greater values it returns incorrect results:

对于更大的值,它返回不正确的结果:

2.2.2 :006 > Time.at(60 * 60 * 24).utc.strftime('%H h %M m')
 => "00 h 00 m"

I suggest using the simplest method I found for this problem:

我建议使用我为这个问题找到的最简单的方法:

  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

You can always adjust returned value to your needs.

您可以随时根据需要调整返回值。

回答by Cyril Duchon-Doris

An answer inspired from Lev Lukomsky's one taking advantage of ActiveSupport::Duration, and handling milliseconds (useful to benchmark code)

灵感来自 Lev Lukomsky 的一个利用 ActiveSupport::Duration 和处理毫秒的答案(对基准代码有用)

# duration in ms modulus number of ms in one second
milliseconds = duration.in_milliseconds % 1.second.in_milliseconds

# duration in seconds modulus number of seconds in one minute
seconds = (duration / 1.second) % (1.minute / 1.second)

# duration in minutes modulus number of minutes in one hour
minutes = (duration / 1.minute) % (1.hour / 1.minute)

# duration in hours modulus number of hours in one day
hours = (duration / 1.hour) % (1.day / 1.hour)

format("%02d:%02d:%02d:%03d", hours, minutes, seconds, milliseconds) #=> "12:05:00:001"

Of course you can extend this easily with days, months, years, etc using related ActiveSupport methods and repeating the same structure.

当然,您可以使用相关的 ActiveSupport 方法并重复相同的结构,以数天、数月、数年等时间轻松地扩展它。

Keep in mind that for too long durations, this may be inaccurate since the duration of 1 month is not fixed in number of days, and I'm not sure how AS:Duration deals with that.

请记住,对于过长的持续时间,这可能不准确,因为 1 个月的持续时间不是固定的天数,我不确定 AS:Duration 是如何处理的。

回答by Daniel

Just to throw in my 2 cents:

只是为了投入我的 2 美分:

Time.at(i).utc.strftime((i < 3600) ? '%-M minutes and %-S seconds' : '%-H hours, %-M minutes, and %-S seconds')

Built off of Xiao Bin's answer.

基于肖斌的回答。