RubyのTimeオブジェクトをto_sしてTime.parseすると違う時刻になる?

タイトルわかりにくいな。要するにこういうこと。

2.1.1 :001 > require 'time'
 => true 
2.1.1 :002 > now = Time.now
 => 2014-11-19 22:27:36 +0900 
2.1.1 :003 > now2 = Time.parse(now.to_s)
 => 2014-11-19 22:27:36 +0900

Time.now して作ったインスタンス now をいったん文字列に変換して、Time.parse したのが now2。当然同じ時刻を示している。

2.1.1 :004 > now
 => 2014-11-19 22:27:36 +0900 
2.1.1 :005 > now2
 => 2014-11-19 22:27:36 +0900

と思いきや、== で比較してみると false が返ってくる。

2.1.1 :006 > now == now2
 => false

どういうことかと、うーんとなった。

で、ググってみると、同じことしてる人がいるもんだね。

 cf. 「Ruby」Timeクラスの比較 – タナカイチロウの日記

どうやら、Ruby の Time クラスは時刻を浮動小数点で持っていて、上のような操作をしてしまうと、厳密に同じ時刻を再現できないらしい。

2.1.1 :007 > now.to_f
 => 1416403656.075245 
2.1.1 :008 > now2.to_f
 => 1416403656.0

なるほどね〜。こりゃ、ハマりどころだわ。
ちなみに、Time.new で作ったインスタンスだとちゃんと true が返ってくる。

2.1.1 :009 > t = Time.new(2014, 11, 19, 22, 30, 0)
 => 2014-11-19 22:30:00 +0900 
2.1.1 :010 > t2 = Time.parse(t.to_s)
 => 2014-11-19 22:30:00 +0900 
2.1.1 :011 > t
 => 2014-11-19 22:30:00 +0900 
2.1.1 :012 > t2
 => 2014-11-19 22:30:00 +0900 
2.1.1 :013 > t == t2
 => true
カテゴリー: Ruby パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください