We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
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.
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.
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