我使用local_time gem来显示用户本地时间的日期,它可以很好地用于已经添加的日期,以显示他们在我的本地时间。
我在添加新日期时遇到了问题,我试图通过HTML表单传递用户本地时间(以及日期)。我认为客户端设备有他们的本地时间,所以我需要抓取它。
现在我正试图添加一个字段到我的表单,如:
= simple_form_for(@link)do |f|
...
= f.text_field :local_client_time, value: local_time("#{Time.now()}")
但是显示的是
August 11, 2014 12:12pm" />
不仅格式错误,实际上显示(应该隐藏),而且还显示utc时间,比我的浏览器时间早5小时,在EST上。
如何在表单上传递用户的本地时间?(可能是js) ?
我也不确定如何在控制器上处理它。我现在有
@link = Link.new(params[:link])
和之后的一些其他逻辑。我不确定如何让rails在创建活动记录实例时处理这个额外的参数(它会忽略它吗?),我也不确定如何使用local_client_time通过隐藏字段传入,因为在日期格式中,rails可以用来实际设置日期字段verified_date
的值
注意:我需要为所有用户显示字段,无论登录与否,但这似乎与local_time gem没关系。唯一的问题似乎是添加具有时间组件的日期字段。在美国东部时间晚上8点之后,它被添加为第二天,然后显示器反映了这一点。另一个字段('content_date')没有这些问题,但对于该字段,我只是使用f.text_field :content_date, id: 'datepicker', size: 10
,在控制器和数据库中的日期字段中没有特殊处理。
两个日期字段看起来很相似:
| content_date | date | YES | | NULL | |
| verified_date | date | YES | | NULL | |
我也想知道验证日期字段实际上应该是datetime,而不是解决这个问题。问题是我不关心时间组件,也从不使用或显示它。对于日期/时间字段,应用程序的最低粒度级别是1天。
我想这样就足够了:
= simple_form_for @link do |f|
...
= f.text_field :local_client_time # This generates some unique ID I believe. Otherwise, define one yourself: id: <your-id>
# javascript
var localTime = new Date();
$('<ID generated through rails for your field>').val(localTime);
Rails将在服务器端接收这个附加参数,只要它是表单的一部分。你需要做的是在你的活动记录模型类(例如local_client_time
)上添加一个参数,然后确保通过强参数过滤器允许(如果你使用Rails 4)。
如果你有一个字段在你的活动记录模型,那么Link.new(params[:link]
)应该做的伎俩,否则你需要在你的模型上定义一个方法(def local_client_time=
),然后将处理输入。
当然也会有一些日期管理服务器端,但这应该不是太大的问题。
在我的应用中解决了这个问题,有很多不同的用户时区实现,这真的让人难以理解,很难测试。我将在底部发布链接,以便看到其他实现。
对于你的直接请求,有一个很好的gem提供了js功能来检测客户端的时区。参考这个
设置完成后,可以这样做:
$(function() {
var detected_zone = Temporal.detect();
$('#user_time_zone').val(detected_zone.timezone.name);
});
设置好时区后,可以使用time. zone.now获取本地时间。
看一下railcast如何在db中跟踪每个用户的时区:link