2

ここに行きます:

Time.zone.now => "Eastern Time (US & Canada)"
Time.zone.now => Wed, 15 Aug 2012 06:05:37 EDT -04:00
Time.zone.now + 39.years => Tue, 15 Aug 2051 06:06:03 EST -05:00

そして、伝説の東部夏時間の終わりは、Ruby on Rails によって 2051 年に終わると予言されています。

他の TimeZone 変更エリアでも機能します。

Time.zone
 => "Pacific Time (US & Canada)" 
1.9.2p180 :003 > Time.zone.now
 => Wed, 15 Aug 2012 03:08:57 PDT -07:00 
1.9.2p180 :004 > Time.zone.now + 39.years
 => Tue, 15 Aug 2051 03:08:57 PST -08:00 

これは Rails 3.0 と Rails 3.2.6 に存在します。

4

1 に答える 1

1

はい、バグのようです。これは Rails ではありませんが、Ruby Timeクラスです。2038年以降の時代に問題があります。

たとえば、Ruby 1.8.7 の場合:

> Time.local(2037,8,16,9,30,15)
 => Sun Aug 16 09:30:15 -0400 2037 
>
> Time.local(2038,8,16,9,30,15)
 => Mon Aug 16 09:30:15 -0500 2038

たとえば、JRuby 1.6.7.2 にはこの問題はありません。

> Time.local(2038,8,16,9,30,15)
 => Mon Aug 16 09:30:15 -0400 2038

64 ビット システムの MRI Ruby では、期間の追加をサポートする ActiveSupport 時間拡張は、最終的に、active_support/core_ext/time/calculations.rb のこのメソッドを介して Time.local または Time.utc を呼び出すことに注意してください。

      # Returns a new Time if requested year can be accommodated by Ruby's Time class
      # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
      # otherwise returns a DateTime
      def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
        ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
      rescue
        offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0
        ::DateTime.civil(year, month, day, hour, min, sec, offset)
      end

問題は、2038年以上の場合、オーバーフロー例外が発生し、代わりにDateTimeが使用されることを期待していたことだと思います。64 ビット システムでは、これは起こりません。

更新: この分析は Ruby 1.9.2+ では正しくありません。Time.local は期待どおりに動作しますが、元の問題は引き続き発生します。

于 2012-08-15T12:14:23.067 に答える