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

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

heroku config:add TZ=America/Los_Angeles 

用户的时间现在始终在PST中 – 无论他们是否在PST时区。

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

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

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

  • 实际上,您可以使用javascript来获取当前时间/时区。 用户的计算机时间可能未正确设置,在这种情况下,您显示的时区将不正确。

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

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

    使用IP地址,您可以获得他们的大致城市和纬度/经度。 有许多gem可以在Ruby Toolbox上执行此操作,例如。 geocoder 。 使用纬度/经度,您可以使用类似timezone区的gem来获取timezone

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

根据您的应用设置方式,有两种方法可以做到这一点。 这些都不是Heroku环境所特有的。

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

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

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

在Application Controller中,您可以执行以下操作;

 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 

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

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

如果您没有用户身份validation,那么您可以回退到javascript。 要做到这一点,你可以在日期对象上使用本机javascript getTimezoneOffset() ,或者甚至更好地使用以下jsTimezoneDetect插件:

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

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

或者你可以使用这个真棒gemhttps://github.com/kbaum/browser-timezone-rails