どのようにしてUnixのタイムスタンプ(Epochからの秒数)をRubyのDateTimeに変換しますか?
DateTime.strptime
はEpochからの秒数を処理できます。数値は文字列に変換する必要があります。
require 'date'
DateTime.strptime("1318996912",'%s')
申し訳ありませんが、シナプス障害の瞬間です。これが本当の答えです。
require 'date'
Time.at(seconds_since_Epoch_integer).to_datetime
簡単な例(これは現在のシステムタイムゾーンを考慮に入れています):
$ date +%s
1318996912
$ irb
Ruby-1.9.2-p180 :001 > require 'date'
=> true
Ruby-1.9.2-p180 :002 > Time.at(1318996912).to_datetime
=> #<DateTime: 2011-10-18T23:01:52-05:00 (13261609807/5400,-5/24,2299161)>
さらなる更新(UTC用):
Ruby-1.9.2-p180 :003 > Time.at(1318996912).utc.to_datetime
=> #<DateTime: 2011-10-19T04:01:52+00:00 (13261609807/5400,0/1,2299161)>
最近の更新:私は1、2週間前にHAサービスに取り組んでいる間にこのスレッドのトップソリューションをベンチマークしました、そしてTime.at(..)
がDateTime.strptime(..)
よりも優れていることに驚きました(更新:ベンチマークを追加)。
# ~ % Ruby -v
# => Ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]
irb(main):038:0> Benchmark.measure do
irb(main):039:1* ["1318996912", "1318496912"].each do |s|
irb(main):040:2* DateTime.strptime(s, '%s')
irb(main):041:2> end
irb(main):042:1> end
=> #<Benchmark ... @real=2.9e-05 ... @total=0.0>
irb(main):044:0> Benchmark.measure do
irb(main):045:1> [1318996912, 1318496912].each do |i|
irb(main):046:2> DateTime.strptime(i.to_s, '%s')
irb(main):047:2> end
irb(main):048:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
irb(main):050:0* Benchmark.measure do
irb(main):051:1* ["1318996912", "1318496912"].each do |s|
irb(main):052:2* Time.at(s.to_i).to_datetime
irb(main):053:2> end
irb(main):054:1> end
=> #<Benchmark ... @real=1.5e-05 ... @total=0.0>
irb(main):056:0* Benchmark.measure do
irb(main):057:1* [1318996912, 1318496912].each do |i|
irb(main):058:2* Time.at(i).to_datetime
irb(main):059:2> end
irb(main):060:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
タイムゾーン処理
将来の人々がこの非常に重要な区別を見逃さないように、これはコメントされていますが、明確にしたいと思います。
DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000
戻り値をUTCで表示し、秒をStringにしてUTC Timeオブジェクトを出力する必要があります。
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
lOCALタイムゾーンに戻り値を表示します。通常はFixNum引数が必要ですが、表示がなくてもTimeオブジェクト自体はまだUTCです。
そのため、両方のメソッドに同じ整数を渡したとしても、クラスの#to_s
メソッドがどのように機能するかによって、2つの異なる結果が得られます。しかし@Eeroは私に2度思い出させなければならなかったので:
Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true
2つの戻り値間の等価比較は、依然としてtrueを返します。繰り返しますが、これは値が基本的に同じであるためです(クラスによって異なりますが、#==
メソッドがこれを処理します)、しかし#to_s
メソッドは大幅に異なる文字列を出力します。とはいえ、文字列を見れば、確かに同じ時間であり、異なるタイムゾーンで印刷されていることがわかります。
メソッド引数の明確化
文書にはまた、「数値の引数が与えられた場合、結果は現地時間である」と書かれています。これは理にかなっていますが、ドキュメントで整数でない引数の例を何も与えていないので、私を少し混乱させました。だから、いくつかの非整数引数の例については:
Time.at("1318996912")
TypeError: can't convert String into an exact number
string引数を使用することはできませんが、Time引数をTime.at
に使用すると、引数のタイムゾーンで結果が返されます。
Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900
****あらゆる点で完全かつ完全に不正確ではないように編集****
日付時刻をUnix形式に変換してから文字列に変換する1つのコマンド
DateTime.strptime(Time.now.utc.to_i.to_s,'%s').strftime("%d %m %y")
Time.now.utc.to_i #Converts time from Unix format
DateTime.strptime(Time.now.utc.to_i.to_s,'%s') #Converts date and time from unix format to DateTime
最後にstrftimeが日付のフォーマットに使われます
例:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
これはあなたがコードを実行した瞬間から未来の秒数の日付を教えてくれます。
time = Time.new + 1000000000 #date in 1 billion seconds
置く(時間)
現在の時間によると、私はそれが047-05-14 05:16:16 +0000
(将来10億秒)を印刷する質問に答えています。
あるいは特定の時間から10億秒をカウントしたい場合は、Time.mktime(year, month,date,hours,minutes)
の形式になります。
time = Time.mktime(1987,8,18,6,45) + 1000000000
置く(「私は10億秒前になるだろう:」+時間)
単にDateが欲しいのであれば、Date.strptime(invoice.date.to_s, '%s')
をinvoice.date
をanFixnum
の形にしてString
に変換することができます。