Friday, July 30, 2010

Limits of Time in Ruby

Was curious about the maximum Time in Ruby and minimum Time in Ruby you could specify via number to the at method, and they seem to be -67768040609636400 and 67768036191694799, at least locally for me in a 64-bit OS X 10.6 environment. The maximum number to not produce a negative year is 67767976233550799:
$ ruby -version
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
$ irb
>> Time.at(-67768040609636400)
=> Fri Jan 01 00:00:00 -0500 -2147481748
>> Time.at(-67768040609636401)
ArgumentError: localtime error
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:302:in `inspect'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:302:in `output_value'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:151:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:263:in `signal_status'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:147:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:146:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:70:in `start'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:69:in `catch'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:69:in `start'
 from /usr/bin/irb:13
Maybe IRB bug!!
>> Time.at(67768036191694799)
=> Wed Dec 31 23:59:59 -0500 -2147481749
>> Time.at(67768036191694800)
ArgumentError: localtime error
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:302:in `inspect'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:302:in `output_value'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:151:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:263:in `signal_status'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:147:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:146:in `eval_input'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:70:in `start'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:69:in `catch'
 from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb:69:in `start'
 from /usr/bin/irb:13
Maybe IRB bug!!
>> Time.at(67767976233550799)
=> Tue Dec 31 23:59:59 -0500 2147483647
>> Time.at(67767976233550800)
=> Wed Jan 01 00:00:00 -0500 -2147483648
These aren't the limits in JRuby, as you can see here:
$ jruby -version
jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20) [x86_64-java]
$ jirb
irb(main):001:0> Time.at(-67768040609636400)
=> Wed Jan 06 09:43:26 -0500 190734449
irb(main):002:0> Time.at(-67768040609636401)
=> Wed Jan 06 09:43:25 -0500 190734449
irb(main):003:0> Time.at(67768036191694799)
=> Fri Dec 25 14:20:30 -0456 -190730650
irb(main):004:0> Time.at(67768036191694800)
=> Fri Dec 25 14:20:31 -0456 -190730650
Tested in MacRuby, and it is like the regular Ruby MRI:
$ macruby -version
MacRuby version 0.6 (ruby 1.9.0) [universal-darwin10.0, x86_64]
$ macirb
irb(main):001:0> Time.at(67767976233550799)
=> 2147483647-12-31 23:59:59 -0500
irb(main):002:0> Time.at(67767976233550800)
=> -2147483648-01-01 00:00:00 -0500
irb(main):003:0> Time.at(-67768040609636400)
=> -2147481748-01-01 00:00:00 -0500
irb(main):004:0> Time.at(-67768040609636401)
ArgumentError: localtime error

irb(main):005:0> Time.at(67768036191694799)
=> -2147481749-12-31 23:59:59 -0500
irb(main):006:0> Time.at(67768036191694800)
ArgumentError: localtime error

However, these numbers seem to differ in 32-bit environments. In codepad, all attempts produce the following error. Steven Hazel of codepad.org stated that this could be a 32-bit OS-specific issue:

Line 1:in `at': bignum too big to convert into `long' (RangeError)
>  from t.rb:1

No comments: