私はこれを行うためのシンプルな/組み込みの方法があると感じていますが、それを見つけることができません。
整数の期間(秒単位)があり、わかりやすい形式で表示したい。
例えば3600は「01:00:00」または「1時間」などと表示されます。
私はtime_ago_in_words(Time.zone.now+3600)
でそれを行うことができますが、それはちょっとしたハックのように感じます。この値をフォーマットするためだけに現在の時間から加算/減算する理由はありません。 duration_in_words()
などがありますか?
ありがとう
参照: http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html
distance_of_time_in_words(3600)
=> "about 1 hour"
要約:
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単語が必要な場合、Option2 H:M:S形式が必要な場合、Option H:M:S形式が必要な場合、 24時間以上かかる場合があります
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"
素敵。
次のようなこともできると思います:
(Time.mktime(0)+3600).strftime("%H:%M:%S")
必要に応じてフォーマットします。
ところで、もともとはTime.at()を使用することを考えていましたが、私のUbuntuのエポック時間は木曜日1月01日01:00:00 +0100 1970であり、予想どおり00:00:00時間ではないようです。
Time.at(3600).strftime("%H:%M:%S")
必要以上に1時間長くなります。
Integer
クラスにカスタムメソッドを追加します。 initializers
フォルダーにpretty_duration.rb
という名前の新しいファイルを作成できます。
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に基づいています
これは、あいまいな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
1日より長い期間に注意してください。
(timing/3600).to_i.to_s.rjust(2,'0') + ":"+Time.at(timing).utc.strftime("%M:%S")
ActiveSupport :: Durationを利用し、ミリ秒を処理するLev Lukomskyのものからヒントを得た回答(ベンチマークコードに有用)
# 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がそれをどのように処理するかわかりません。
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
必要に応じて、戻り値をいつでも調整できます。
hours = 3.5456
value = (hours*60).divmod(60).map{ |a| "%02d"%[a.floor] }.join(":")
=> "03:32"