tomciopp
tomciopp

Reputation: 2742

Calculating a time zone based on location [Rails]

I have a model that has a latitude, longitude, and datetime attributes and I want to be able to calculate the timezone of that location and set it for each individual instance of the model. Here is the code that I have written to get the time zone is there something I am missing?

require 'nokogiri'
require 'open-uri'

before_validation :set_current_time_zone

def set_current_time_zone
  Time.zone = find_timezone_based_on_location
end

def find_time_zone_based_on_location
  url = "http://www.earthtools.org/timezone-1.1/#{self.latitude}/#{self.longitude}"
  doc = Nokogiri::XML(open(url))
  offset = doc.at_xpath('//offset').text().to_i
  if offset == -5
    "Eastern Time (US & Canada)"
  ....
  elsif offset == -8 
    "Pacific Time (US & Canada)"
  end
end

Is there something that I am missing as to why this is not setting the correct time?

Upvotes: 2

Views: 686

Answers (2)

tomciopp
tomciopp

Reputation: 2742

I was able to get the code to work by changing the set_current_time_zone to the following:

def set_current_time_zone
  self.attributeActiveSupport::TimeZone[find_time_zone_based_on_location].local_to_utc(self.attribute)
end

This will find the correct Time zone and then translate that time into UTC.

Upvotes: 0

naren
naren

Reputation: 937

I am not sure if you really want to set time zone at each instance of the model. As per MVC as the model is accessed from Controller, setting time_zone at the controller level should be good enough. Once the time zone is set at the controller level, all calculations related to time are handled for that request in the time_zone set in the filter. Below is the code.

 def set_time_zone
   old_time_zone = Time.zone
   Time.zone = find_time_zone_based_on_location
   yield
  ensure
    Time.zone = old_time_zone
  end

And in the controller where you want to set time zone you define the around filter. find_time_zone_based_on_location(as defined by you above) can be helper method in application_controller

 around_filter :set_time_zone

Upvotes: 1

Related Questions