web-dev-qa-db-ja.com

UNIXのタイムスタンプ(エポックからの秒数)をRubyのDateTimeに変換するにはどうすればいいですか?

どのようにしてUnixのタイムスタンプ(Epochからの秒数)をRubyのDateTimeに変換しますか?

340
Tronathan

DateTime.strptimeはEpochからの秒数を処理できます。数値は文字列に変換する必要があります。

require 'date'
DateTime.strptime("1318996912",'%s')
324
steenslag

申し訳ありませんが、シナプス障害の瞬間です。これが本当の答えです。

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>
602
Adam Eberlin

タイムゾーン処理

将来の人々がこの非常に重要な区別を見逃さないように、これはコメントされていますが、明確にしたいと思います。

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

****あらゆる点で完全かつ完全に不正確ではないように編集****

59
WattsInABox

日付時刻を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"
8

これはあなたがコードを実行した瞬間から未来の秒数の日付を教えてくれます。

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億秒前になるだろう:」+時間)

1
sbutterworth

単にDateが欲しいのであれば、Date.strptime(invoice.date.to_s, '%s')invoice.dateをanFixnumの形にしてStringに変換することができます。

0
pjammer