Ruby Time.parse, Time. strptime and Time zones

This is a note to myself. So it might not be entirly useful to other folks.

Note: my system's time zone is set to +1000 Brisbane time.

Recently I stumbled accross a bug in our code base where, Time.parse was used (incorrectly) to create a Time object from a string. Time and specially Time.zone related stuff tend to be very complicated and is quite easy to misunderstand.

The whole codebase was full of lines of code like the following:

Time.parse('2013-09-15 12:30:05').in_time_zone('Brisbane')  
=> Sun, 15 Sep 2013 12:30:05 EST +10:00

What this line was intended to do was to give a Time object that represent 2013-09-15 12:30:05 in Brisbane time zone.

However, what it does is to give out a Time object that represent 2013-09-15 12:30:05 in whatever the current system's set time zone, and then spit out a new Time object with that time 'converted' to Brisbane time zone.

So if this code was run on a system whose time zone is set to Estern Standard Time (US), it would first create a Time object that represents 2013-09-15 12:30:05 in EST. And then 'convert' it to Brisbane time zone.

Which is not what we want.

To do what we really want (as noted above). We should:

Time.parse('2013-09-15 12:30:05 +1000')  
=> 2013-09-15 12:30:05 +1000

However, if we were to do:

Time.parse('2013-09-15 +1000')  
=> 2013-09-15 00:00:00 +1000

Time.parse is actually ignoring the specified time zone. But it's using +1000 anyway because it's my system's time zone. So let's try something different.

Time.parse('2013-09-15 +1100')  
=> 2013-09-15 00:00:00 +1000

Note that it ignored the supplied +1100 time zone.

Time.strptime is a more 'visible' way of expressing what we need to do.

Time.strptime('2013-09-15 12:30:05 +1000', '%Y-%m-%d %I:%M:%S %z')  
=> 2013-09-15 12:30:05 +1000

The above code is far more explicit and is hard to misunderstand. IMHO we should use this over the previous Time.parse examples. For better readability and also because it will make it harder to create bugs like the one I found.

Cheers!