LoginSignup
46
38

More than 5 years have passed since last update.

秒を時間表示へ変換する

Last updated at Posted at 2014-05-18

前提条件

  • 秒が正であること。

負の場合は適当に符号をひっくり返して元に戻したりしてください。

手順

適当な日の0時のTimeオブジェクトを取得し、そのオブジェクトに目的の秒数を加算し、Time#strftimeで変換後の値を取得。
ただし目的の秒数が86400秒(1日)を超える場合には、超えないように処理しておく。

10000秒は何時間何分何秒?

require 'time'
sec = 10000
day = sec.to_i / 86400
(Time.parse("1/1") + (sec - day * 86400)).strftime("#{day}日%H時間%M分%S秒")
=> "0日02時間46分40秒"

2時間46分40秒。

1000000秒は?secへの代入を除いて一行で書きたい。

sec = 1000000
(Time.parse("1/1") + sec - (day = sec.to_i / 86400) * 86400).strftime("#{day}日%H時間%M分%S秒")
=> "11日13時間46分40秒"

一行で書けたけど、86400が多くて、なんか根本的にイマイチ。

Numeric#divmodを使ってみてはいかがでしょう。

self を other で割った商 q と余り r を、 [q, r] という 2 要素の配列にして返します。 商 q は常に整数ですが、余り r は整数であるとは限りません。
instance method Numeric#divmod

sec = 1000000
day, sec_r = sec.divmod(86400)
=> [11, 49600]
(Time.parse("1/1") + sec_r).strftime("#{day}日%H時間%M分%S秒")
=> "11日13時間46分40秒"

じゃあこれを一行で書いてみてよ。

Numeric#divmod の返値が要素二つの配列と決まっているので、かなり強引ですが Enumerable#each_sliceを使ってみましょう。

sec = 1000000
sec.divmod(86400).each_slice(2).map { |day, sec_r| (Time.parse("1/1") + sec_r).strftime("#{day}日%H時間%M分%S秒") }.first
=> "11日13時間46分40秒"

秒以下表示は?例えば99999.9秒とか?

Time#strftimeでミリ秒表示をする%Lを使いましょう。

sec = 99999.9
day, sec_r = sec.divmod(86400)
=> [1, 13599.899999999994]
(Time.parse("1/1") + sec_r).strftime("#{day}日%H時間%M分%S秒%L")
=> "1日03時間46分39秒899"

…残念。演算誤差が出ました。
ではRationalクラスを使ってみましょう。

sec = 99999.9
sec_rationaled = Rational(sec.to_s)
=> (999999/10)
day, sec_r = sec_rationaled.divmod(86400)
=> [1, (135999/10)]
(Time.parse("1/1") + sec_r).strftime("#{day}日%H時間%M分%S秒%L")
=> "1日03時間46分39秒900"

ここまでやるかどうかはお任せしますw

表示から余分な0を除く

Time#strftimeで%Hの場合、一桁だと0で埋められてしまいます。

(Time.parse("1/1") + 10000 + 15 * 60 + 25).strftime("%H時間%M分%S秒")
=> "03時間02分05秒"

%とHやMとの間に-を入れると余分な0を消せます。

(Time.parse("1/1") + 10000 + 15 * 60 + 25).strftime("%-H時間%-M分%-S秒")
=> "3時間2分5秒"

その他いろいろあります。

^: 大文字で出力を行なう
#: 小文字であれば大文字に、大文字であれば小文字に変更する
-: 左寄せにする(0埋めや空白埋めを行わない)
_: 空白埋めにする
0: 0埋めにする
数値: 表示桁数を指定する

t = Time.now                         #=> 2010-09-05 15:41:17 0900
t.strftime("Printed on %m/%d/%Y")    #=> "Printed on 09/05/2010"
t.strftime("Printed on %m/%-d/%_6Y") #=> "Printed on 09/5/  2010"
t.strftime("at %I:%M%p")             #=> "at 03:41PM"
t.strftime("at %I:%M%#p")            #=> "at 03:41pm"

instance method Time#strftime

参考

46
38
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
38