4

I have to add a time_zone_select into my Rails application. I was considering some gems to put a default value based on the user request, but I've seen that the project has already installed geocode gem for this purpose.

Is there any way of get the timezone through this gem?

Fran Martinez
  • 2,994
  • 2
  • 26
  • 38

3 Answers3

11

You cannot get timezone directly from geocoder gem. It can just give you location.

You can use the gem below to get the timezone for a particular zone or for (lat,long) values.

https://github.com/panthomakos/timezone

timezone = Timezone::Zone.new :latlon => [-34.92771808058, 138.477041423321]
timezone.zone
=> "Australia/Adelaide"
timezone.time Time.now
=> 2011-02-12 12:02:13 UTC
  • I was trying this two minuts ago, but I get this error: Timezone::Error::InvalidConfig: missing username https://github.com/panthomakos/timezone/issues/34 – Fran Martinez Jul 07 '15 at 12:44
  • Have you added your api key? as shown below ? Timezone::Configure.begin do |c| c.google_api_key = 'your_google_api_key_goes_here' c.google_client_id = 'your_google_client_id' end – Nitin Satish Salunke Jul 07 '15 at 13:05
  • You have to get api key from google and configure it. – Nitin Satish Salunke Jul 07 '15 at 13:06
  • I was missing to configure a username (it worth it to read the full README, hehe): https://github.com/panthomakos/timezone#getting-the-timezone-for-a-specific-latitude-and-longitude – Fran Martinez Jul 08 '15 at 06:01
1

This seems to be doing the trick for me (for most of the timezones I've tested).

All the code I put here are methods in the controller (in my case, in ApplicationController).

def request_location
  if Rails.env.test? || Rails.env.development?
    Geocoder.search("your.public.ip.here").first
  else
    request.location
  end
end

def get_time_zone
  time_zone = request_location.data["time_zone"]
  return ActiveSupport::TimeZone::MAPPING.key(time_zone) || "UTC"
end

Of course, you should substitute your.public.ip.here for your actual public ip, or something similar. I put an IP here so that the response that Geocoder gives has the same format as the one from the request.

I'm happy to hear comments on the code.

jwpfox
  • 5,124
  • 11
  • 45
  • 42
0

I have seen an alternative way to do this, but the proposal of Nitin Satish is still better. Anyway, it is good to have more than one option:

 loc = request.location.data
 tzc = TZInfo::Country.get(loc["country_code"])
 timezone = Timezone::Zone.new zone:tzc.zone_names.first
 timezone.local_to_utc(Time.now)
Fran Martinez
  • 2,994
  • 2
  • 26
  • 38
  • 3
    Just as a note, you're looking up by country, and taking the first time zone in that country. This wouldn't necessarily be valid in e.g. the USA. – Ryan Taylor Feb 24 '16 at 22:58
  • Completely true. Thanks for this point. It only works for countries with just one time zone – Fran Martinez Feb 25 '16 at 10:08