Ruby 2.4 DateTime#to_time & Time#to_time keeps info

Sushant Mittal

By Sushant Mittal

on September 19, 2017

This blog is part of our  Ruby 2.4 series.

In Ruby, DateTime#to_time and Time#to_time methods can be used to return a Time object.

In Ruby 2.3, these methods convert time into system timezone offset instead of preserving timezone offset of the receiver.

Ruby 2.3

1
2> datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
3 #=> #<DateTime: 2017-05-16T10:15:30+09:00 ((2457890j,4530s,0n),+32400s,2299161j)>
4> datetime.to_time
5 #=> 2017-05-16 06:45:30 +0530
6
7> time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
8 #=> 2017-05-16 10:15:30 +0900
9> time.to_time
10 #=> 2017-05-16 06:45:30 +0530
11

As you can see, DateTime#to_time and Time#to_time methods return time in system timezone offset +0530.

Ruby 2.4 fixed DateTime#to_time and Time#to_time.

Now, DateTime#to_time and Time#to_time preserve receiver's timezone offset info.

Ruby 2.4

1
2> datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
3 #=> #<DateTime: 2017-05-16T10:15:30+09:00 ((2457890j,4530s,0n),+32400s,2299161j)>
4> datetime.to_time
5 #=> 2017-05-16 10:15:30 +0900
6
7> time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
8 #=> 2017-05-16 10:15:30 +0900
9> time.to_time
10 #=> 2017-05-16 10:15:30 +0900
11

Since this is a breaking change for Rails application upgrading to ruby 2.4, Rails 4.2.8 built a compatibility layer by adding a config option. ActiveSupport.to_time_preserves_timezone was added to control how to_time handles timezone offsets.

Here is an example of how application behaves when to_time_preserves_timezone is set to false.

1> ActiveSupport.to_time_preserves_timezone = false
2
3> datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
4 #=> Tue, 16 May 2017 10:15:30 +0900
5> datetime.to_time
6 #=> 2017-05-16 06:45:30 +0530
7
8> time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
9 #=> 2017-05-16 10:15:30 +0900
10> time.to_time
11 #=> 2017-05-16 06:45:30 +0530

Here is an example of how application behaves when to_time_preserves_timezone is set to true.

1> ActiveSupport.to_time_preserves_timezone = true
2
3> datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
4 #=> Tue, 16 May 2017 10:15:30 +0900
5> datetime.to_time
6 #=> 2017-05-16 10:15:30 +0900
7
8> time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
9 #=> 2017-05-16 10:15:30 +0900
10> time.to_time
11 #=> 2017-05-16 10:15:30 +0900

If you liked this blog, you might also like the other blogs we have written. Check out the full archive.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, React.js, React Native, remote work,open source, engineering & design.