我觉得有一种简单/内置的方法可以做到这一点,但我找不到它。
我有一个整数的持续时间(以秒为单位),我希望以友好的格式显示它。
e.g。 3600将显示为“01:00:00”或“1小时”或其他内容。
我可以用time_ago_in_words(Time.zone.now+3600)
来做,但这感觉有点像黑客,没有理由加上/减去当前时间只是为了格式化这个值。有duration_in_words()
还是什么?
由于
答案 0 :(得分:182)
总结:
假设total_seconds = 3600
选项1:
distance_of_time_in_words(total_seconds) #=> "about 1 hour"
选项2:
Time.at(total_seconds).utc.strftime("%H:%M:%S") #=> "01:00:00"
选项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"
如果你想要单词,请使用 Option1 ;如果你想要H:M:S格式, Option2 ,如果你想要H:M,则使用 Option3 : S格式,可以超过24小时
答案 1 :(得分:75)
请参阅:http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html
distance_of_time_in_words(3600)
=> "about 1 hour"
答案 2 :(得分:38)
Ruby的字符串%
运算符太过不受重视并且被遗忘了。
"%02d:%02d:%02d:%02d" % [t/86400, t/3600%24, t/60%60, t%60]
鉴于 t 是一个以秒为单位的持续时间,它会发出一个零填充冒号分隔的字符串,包括天数。例如:
t = 123456
"%02d:%02d:%02d:%02d" % [t/86400, t/3600%24, t/60%60, t%60]
=> "01:10:17:36"
可爱。
答案 3 :(得分:20)
我想你也可以这样做:
(Time.mktime(0)+3600).strftime("%H:%M:%S")
根据需要进行格式化。
BTW,最初我想过使用Time.at(),但似乎我的Ubuntu上的EPOCH时间是Thu Jan 01 01:00:00 +0100 1970而不是00:00:00小时,正如我预期的那样,因此如果我这样做:Time.at(3600).strftime("%H:%M:%S")
给了我超过想要的1小时。
答案 4 :(得分:12)
向Integer
课程添加自定义方法。您可以在pretty_duration.rb
文件夹中创建名为initializers
的新文件:
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
在项目的任何位置调用seconds.pretty_duration
:
275.pretty_duration # => "04:35"
9823.pretty_duration # => "02:43:43"
此答案建立在Lev Lukomsky's Code
上答案 5 :(得分:7)
这个方法使用模糊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
答案 6 :(得分:7)
ActiveSupport::Duration.build
+ inspect
为您提供有效的结果
>> ActiveSupport::Duration.build(125557).inspect
=> "1 day, 10 hours, 52 minutes, and 37 seconds"
答案 7 :(得分:4)
请注意持续时间超过一天。
(timing/3600).to_i.to_s.rjust(2,'0') + ":"+Time.at(timing).utc.strftime("%M:%S")
答案 8 :(得分:3)
使用Time.utc.strftime
仅适用于总时数小于24 时的值:
2.2.2 :004 > Time.at(60 * 60).utc.strftime('%H h %M m')
=> "01 h 00 m"
对于更大的值,它会返回不正确的结果:
2.2.2 :006 > Time.at(60 * 60 * 24).utc.strftime('%H h %M m')
=> "00 h 00 m"
我建议使用我在这个问题上找到的最简单的方法:
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
您可以随时根据需要调整返回值。
答案 9 :(得分:1)
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"
当然,您可以使用相关的ActiveSupport方法并重复相同的结构,轻松地将其扩展为几天,几个月,几年等。
请记住,持续时间太长可能不准确,因为1个月的持续时间不是固定的天数,而且我不确定AS:Duration如何处理该时间。
答案 10 :(得分:0)
hours = 3.5456
value = (hours*60).divmod(60).map{ |a| "%02d"%[a.floor] }.join(":")
=> "03:32"
答案 11 :(得分:0)
向@ joshua-pinter喊出最好的答案(以评论的形式)。
使用嵌入式替换dotiw
gem可以更好地控制输出的准确性,以适应不同的需求:
https://github.com/radar/distance_of_time_in_words
示例查看代码:
%label
Logoff after:
- expire_in = distance_of_time_in_words(Time.now, Time.now + user.custom_timeout.minutes, :only => [:minutes, :hours, :days])
= expire_in
结果如下:
Logoff after: 1 day, 13 hours, and 20 minutes
答案 12 :(得分:0)
只需投入我的2美分:
Time.at(i).utc.strftime((i < 3600) ? '%-M minutes and %-S seconds' : '%-H hours, %-M minutes, and %-S seconds')
以小斌的答案为基础。