0

I have a simple time zone field in a form like so:

<div class="field">
  <%= f.label :time_zone %><em> (appointment times will be displayed in your timezone)</em><br>
  <%= f.select :time_zone, time_zone_options_for_select(f.object.time_zone, nil, ActiveSupport::TimeZone), {include_blank: true}, class: "form-control" %>
</div>

I have read elsewhere best practice is to prepopulate the field with the timezone of the IP address of the user, and that will be accepted by the user 99% of the time (and in cases where it isn't the user's timezone, they can simply change it)

How do I achieve this in a ruby on rails app?

stevec
  • 41,291
  • 27
  • 223
  • 311
  • 1
    Does this answer your question? [Auto detect user's timezone using his ip in rails](https://stackoverflow.com/questions/6280872/auto-detect-users-timezone-using-his-ip-in-rails) – Cassandra S. Jan 09 '21 at 15:43
  • @CassandraS. it certainly helps, by leading [here](https://stackoverflow.com/a/1809974/5783745) which allows us to find the timezone offset (from GMT I believe), with `-new Date().getTimezoneOffset()/60;`. But I'm still unsure how to map that to an `ActiveSupport::TimeZone`. I hope it is common enough that there's be a 'rails way' – stevec Jan 09 '21 at 15:47
  • You should really read the comments on that answer. Using `getTimezoneOffset` to determine timezones is deeply flawed due to Daylight savings time. – max Jan 09 '21 at 16:12

1 Answers1

2

To lookup locations based on the users IP you need to use an external API such as IPStack - there is no "rails way" as its not a feature of Rails.

The Geocoder gem is commonly used for this and it it has a decent list of service providers available for geocoding. After setting up geocoder you can do a lookup by IP:

results = Geocoder.search("172.56.21.89")
results.first.time_zone

Note that the actual returned fields in the result depends on what backend service is used. It is also possible to just use the API of whatever service you want to use directly with Net::HTTP or any HTTP client of your choice.

max
  • 96,212
  • 14
  • 104
  • 165
  • You can also do the lookup on the client side. I'm guessing there is tons of Yarn packages for this. https://yarnpkg.com/?q=ip%20lookup&p=1 – max Jan 09 '21 at 16:14
  • I agree using offset is a bad idea. But what do you think of [this](https://stackoverflow.com/a/44935836/5783745) approach: `console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)` (returns for me: `Australia/Sydney`) – stevec Jan 10 '21 at 06:10
  • I guess the system TZ is actually a bit better then an ip based lookup. Browser support looks decent. – max Jan 10 '21 at 07:48