Watch your UTCing…

April 15, 2010

After a good few hours of investigating a bug at work yesterday, I came across a weird Ruby feature…. The #utc method on Time objects is destructive and modifies the receiver.

$ irb<br /> ruby-1.8.6-p383 > a = Time.now<br /> => Wed Apr 14 15:36:21 +0100 2010<br /> ruby-1.8.6-p383 > a.utc<br /> => Wed Apr 14 14:36:21 UTC 2010<br /> ruby-1.8.6-p383 > a<br /> => Wed Apr 14 14:36:21 UTC 2010

This is actually in the Ruby docs, however who reads those? This is kind of unexpected behaviour, as in most cases in Ruby (however this is more of a Rails thing), if there are two methods the more dangerous of the two is suffixed by an exclamation mark. A good example is String#strip and String#strip!. The version without an exclamation mark doesn’t modify the original object, however the version with does:

``After a good few hours of investigating a bug at work yesterday, I came across a weird Ruby feature…. The #utc method on Time objects is destructive and modifies the receiver.

$ irb<br /> ruby-1.8.6-p383 > a = Time.now<br /> => Wed Apr 14 15:36:21 +0100 2010<br /> ruby-1.8.6-p383 > a.utc<br /> => Wed Apr 14 14:36:21 UTC 2010<br /> ruby-1.8.6-p383 > a<br /> => Wed Apr 14 14:36:21 UTC 2010

This is actually in the Ruby docs, however who reads those? This is kind of unexpected behaviour, as in most cases in Ruby (however this is more of a Rails thing), if there are two methods the more dangerous of the two is suffixed by an exclamation mark. A good example is String#strip and String#strip!. The version without an exclamation mark doesn’t modify the original object, however the version with does:

``

So if you are going to use #utc, be careful and make sure it you aren’t reliant on the time offset later. You should really be using #dup or #getutc which won’t modify the receiver:

$ irb<br /> ruby-1.8.6-p383 > b = Time.now<br /> => Wed Apr 14 15:36:59 +0100 2010<br /> ruby-1.8.6-p383 > b.getutc<br /> => Wed Apr 14 14:36:59 UTC 2010<br /> ruby-1.8.6-p383 > b<br /> => Wed Apr 14 15:36:59 +0100 2010

This is present in all current versions of Ruby, so upgrading won’t help either!