Skip to content

Instantly share code, notes, and snippets.

@pda
Created November 7, 2011 12:43
Show Gist options
  • Save pda/1344837 to your computer and use it in GitHub Desktop.
Save pda/1344837 to your computer and use it in GitHub Desktop.
Ruby Time usec float bug?

Ruby Time usec float bug?

Most of the time-modification methods in ActiveSupport use Time#change which boils down to instantiating a new Time object.

If Time#change is passed a null-change hash, e.g. {} or { :month => 0 }, then the resulting Time object should compare equally to the original.

This appears to be the case in Mac OS X (Ruby 1.9.3-p0 and 1.9.2-p290) but does not appear to be the case in Linux (Ruby 1.9.2-p290). The inequality is because the Time object holds sub-usec precision, while Time#usec returns a Fixnum representation. However, that doesn't explain the different in behaviour between Mac OS X and Linux.

To gather more information, please comment below with the output of these commands. The output from ruby should be 0.0, but in Linux small floats like 2.67e-07 occur.

ruby --version; \
uname -a; \
ruby -e "t = Time.now; p Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec, t.usec) - t"

Cheers!
Paul

UPDATE

@d11wtq points out that this can be achieved by passing Rational(t.nsec, 1000) instead of t.usec to Time.local. However, Time#nsec doesn't exist in Ruby 1.8.7 which is still supported by ActiveSupport. Less importantly, Rational needs to be loaded from stdlib in Ruby 1.8.7, while it's provided by core in Ruby 1.9.

@pda
Copy link
Author

pda commented Nov 7, 2011

ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]
Darwin paulbookpro.local 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug  9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64
0.0

@pda
Copy link
Author

pda commented Nov 7, 2011

ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]
Darwin paulbookpro.local 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug  9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64
0.0

@pda
Copy link
Author

pda commented Nov 7, 2011

ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
Linux ip-... 2.6.32-312-ec2 #24-Ubuntu SMP Fri Jan 7 18:31:34 UTC 2011 i686 GNU/Linux
-9.01e-07

@pda
Copy link
Author

pda commented Nov 7, 2011

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
Linux ip-... 2.6.38-8-virtual #42-Ubuntu SMP Mon Apr 11 04:06:34 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
-1.79e-07

@d11wtq
Copy link

d11wtq commented Nov 7, 2011

You need to account for any nanoseconds that are present, since OS X doesn't handle them, but Linux does:

t - Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec, Rational(t.nsec, 1000))
# => 0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment