Javascript Rails:如何在使用 Heroku 时获取当前用户的时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12326570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:43:47  来源:igfitidea点击:

Rails: How to get the current user's time zone when using Heroku

javascriptruby-on-railsheroku

提问by ill_always_be_a_warriors

I set the time zone of our site on Heroku to Pacific Standard Time (PST) using:

我使用以下方法将我们网站在 Heroku 上的时区设置为太平洋标准时间 (PST):

heroku config:add TZ=America/Los_Angeles

Times for users are now always in PST--whether or not they are in the PST time zone.

用户的时间现在总是在 PST - 无论他们是否在 PST 时区。

What's the best way to get the user's actual time zone (i.e. the time zone of where they are physically located)?

获取用户实际时区(即他们实际所在的时区)的最佳方法是什么?

I'm guessing that this can be solved using Rails (or Javascript?), as opposed to Heroku.

我猜这可以使用 Rails(或 Javascript?)解决,而不是 Heroku。

回答by ronalchn

There are two ways to do this.

有两种方法可以做到这一点。

  • Indeed, you can use javascript to fetch their current time/timezone. There is the possibility that the user's computer time is not set correctly, in which case the time zone you display will not be correct.

    Because you are using Rails, a recommended way is to get javascript already bundled as a gem, like detect_timezone_rails. This makes it easy to install (because it is all bundled automatically in the asset pipeline.

  • You can use the IP address to infer their country and time zone. The danger in this case is that a user may be using a proxy. Also, while the IP address generally has city-level resolution, it may be more or less accurate, which may in rare cases give the wrong time zone.

    Using the IP address, you can get their approximate city and latitude/longitude. There are many gems that can do this on Ruby Toolbox, eg. geocoder. With the latitude/longitude, you can get the time zone using a gem like timezone.

  • 事实上,您可以使用 javascript 来获取他们当前的时间/时区。有可能是用户的电脑时间设置不正确,在这种情况下您显示的时区将不正确。

    因为您使用的是 Rails,所以推荐的方法是将 javascript 捆绑为 gem,例如detect_timezone_rails. 这使其易于安装(因为它全部自动捆绑在资产管道中。

  • 您可以使用 IP 地址来推断他们的国家和时区。这种情况下的危险在于用户可能正在使用代理。此外,虽然 IP 地址通常具有城市级别的分辨率,但它可能或多或少准确,在极少数情况下可能会给出错误的时区。

    使用 IP 地址,您可以获得他们的大致城市和纬度/经度。有很多 gems 可以在Ruby Toolbox上做到这一点,例如。geocoder. 通过纬度/经度,您可以使用像timezone.

You can also use one of the above, and allow the user to manually change their time zone on your website (either storing this setting in a database if registered, or as a cookie on their browser). This is useful in case you got the timezone wrong.

您还可以使用上述方法之一,并允许用户在您的网站上手动更改他们的时区(将此设置存储在数据库中(如果已注册,或作为浏览器上的 cookie)。这在您弄错时区的情况下很有用。

回答by ADAM

There is a couple of ways you could do this depending on how you app is set up. None of which are unique to the Heroku environment.

有几种方法可以做到这一点,具体取决于您的应用程序的设置方式。这些都不是 Heroku 环境独有的。

If your app allows users to sign up then you most probably have a User model, and you may be using the Devise gem for authentication/signup. Add a field to your db (:time_zone) and store the users time zone in this field when they sign up.

如果您的应用允许用户注册,那么您很可能有一个 User 模型,并且您可能正在使用 Devise gem 进行身份验证/注册。在您的数据库 (:time_zone) 中添加一个字段,并在用户注册时将时区存储在该字段中。

>> rails generate migration add_time_zone_to_users time_zone:string
>> rake db:migrate

Rails gives you a handy time_zone_select form helper which gives you a select list with all the Time zones in it which you can display to your user. Add it to the user sign up form and allow the user to set their time zone when signing up. http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/time_zone_select

Rails 为您提供了一个方便的 time_zone_select 表单助手,它为您提供了一个包含所有时区的选择列表,您可以将其显示给您的用户。将其添加到用户注册表单并允许用户在注册时设置他们的时区。 http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/time_zone_select

In your Application Controller you can then do something like this;

在您的应用程序控制器中,您可以执行以下操作;

before_filter :set_time_zone

def set_time_zone
    #current user is a devise method see https://github.com/plataformatec/devise
    Time.zone = current_user.time_zone if current_user
end

Then when you display a date in your app call .in_time_zoneon the time instance which will display the time in the users time zone.

然后,当您在应用程序中显示日期.in_time_zone时,会在时间实例上调用将显示用户时区的时间。

<%= Time.now.in_time_zone %> or <%= @your_model.created_at.in_time_zone %> 

If you don't have user authentication then you could fall back to javascript. To do this you could use the native javascript getTimezoneOffset()on the date object, or even better use the following jsTimezoneDetect plugin:

如果您没有用户身份验证,那么您可以回退到 javascript。为此,您可以getTimezoneOffset()在日期对象上使用本机 javascript ,甚至更好地使用以下 jsTimezoneDetect 插件:

http://www.pageloom.com/automatic-timezone-detection-with-javascript

http://www.pageloom.com/automatic-timezone-detection-with-javascript

Finally you could use a hybrid of both and firstly detect their time zone offset using javascript and then store this value in a rails session/cookie and then use a before_filter to set the Time.zone as above but based on the session time_zone value previously calculated in javascript.

最后,您可以使用两者的混合,首先使用 javascript 检测它们的时区偏移,然后将此值存储在 Rails 会话/cookie 中,然后使用 before_filter 设置 Time.zone 如上所述,但基于先前计算的会话 time_zone 值在 JavaScript 中。

回答by Mohamed Emad Hegab

Or you can use this awesome gem https://github.com/kbaum/browser-timezone-rails

或者你可以使用这个很棒的 gem https://github.com/kbaum/browser-timezone-rails