【问题标题】:datetime_select not displaying in utcdatetime_select 未以 UTC 显示
【发布时间】:2013-10-23 20:38:34
【问题描述】:

在我的 rails 应用程序中,我希望在原始 UTC 时间中设置和显示某些差旅费用。

我已将此添加到我的 config/application.rb

config.time_zone = 'UTC'
config.active_record.default_timezone = :utc

似乎有一个集合(空白 datetime_select)、一个保存(作为 UTC 存储在 db 中)、一个显示( 和一个修改(预填充的 datetime_select)。

我在设置、保存或显示方面没有问题。我为该集合添加了一个修复程序 - 一个 before_save 调用以将“+0000”附加到时间属性。但是我在修改日期时间时遇到了问题。

当我查看编辑页面时,datetime_select 会显示之前保存的日期时间。但是,它会显示 6 小时前的小时数。它将显示下午 4 点,而不是晚上 10 点。

这是我的表格 datetime_select:

<%= activity_log_item.object.date.utc %>
<%= activity_log_item.datetime_select :date,
  ampm: true,
  use_short_month: true,
  minute_step: 15, order: [:month, :day, :year, :hour, :minute] %>
</td>

第一行将打印出预期的时间(晚上 10 点),我已经确认这与数据库中的时间相同。但是,datetime_select 表单将显示下午 4 点。

我希望我的应用程序中的所有时间都以 UTC 设置、保存和显示,除非我明确解析它 - 例如使用 Time.zone =.in_time_zone

我使用的是 Rails 3.2.12。

【问题讨论】:

  • 另外值得注意的是,当我刷新页面时,它会将 datetime_select 预填充时间切换为 utc - to local - to utc。并非始终如一,但经常发生。

标签: ruby-on-rails datetime datetime-select


【解决方案1】:

您需要在您的应用程序中专门使用Time.zone.nowTime.now.in_time_zone,以强制Rails 使用您在配置文件中设置的时区。要将 date_select 对象默认为 UTC 时间,只需使用 new_record.date = Time.zone.now 初始化新记录,可能在控制器的 new 操作中。

背景

默认情况下,Rails 会将所有日期时间字段转换为 UTC,然后再将它们存储到数据库中。当 Rails 读回一条记录时,它会将该 UTC 时间戳转换为配置文件中指定的区域。 Time.now 将在您的 Web 服务器配置使用的时区中返回一个 Time 对象。 Time.zone.now 会将系统时间转换为配置文件中的时区。

示例

这是一个实际的例子。我的计算机(又名服务器)是在 EST 中配置的。我有一个配置为使用 PST 的 Rails 应用程序。数据库以 UTC 存储所有内容

1.9.3p286 > Time.now
 => 2013-11-12 13:33:40 -0500 
1.9.3p286 > Time.now.zone
 => "EST" 
1.9.3p286 > Time.now.in_time_zone
 => Tue, 12 Nov 2013 10:33:40 PST -08:00 
1.9.3p286 > Time.now.in_time_zone.zone
 => "PST" 
1.9.3p286 > Time.zone.now
 => Tue, 12 Nov 2013 10:33:40 PST -08:00 
1.9.3p286 > Time.zone.now.zone
 => "PST" 
1.9.3p286 > Time.parse("12:34:56")
 => 2013-11-12 12:34:56 -0500 
1.9.3p286 > Time.parse("12:34:56").zone
 => "EST" 
1.9.3p286 > Time.parse("12:34:56").in_time_zone
 => Tue, 12 Nov 2013 09:34:56 PST -08:00 
1.9.3p286 > Time.parse("12:34:56").in_time_zone.zone
 => "PST" 
1.9.3p286 > Time.zone.parse("12:34:56")
 => Tue, 12 Nov 2013 12:34:56 PST -08:00 
1.9.3p286 > Time.zone.parse("12:34:56").zone
 => "PST" 
1.9.3p286 > Time.parse("12:34:56 UTC")
 => 2013-11-12 12:34:56 UTC 
1.9.3p286 > Time.parse("12:34:56 UTC").zone
 => "UTC" 
1.9.3p286 > Time.parse("12:34:56 UTC").in_time_zone
 => Tue, 12 Nov 2013 04:34:56 PST -08:00 
1.9.3p286 > Time.parse("12:34:56 UTC").in_time_zone.zone
 => "PST" 
1.9.3p286 > Time.zone.parse("12:34:56 UTC") # Note that the time is parsed as UST and then converted to PST
 => Tue, 12 Nov 2013 04:34:56 PST -08:00 
1.9.3p286 > t = TripTicket.first
 => #<TripTicket ...> 
1.9.3p286 > t.appointment_time # Reading a datetime field from the database
 => Thu, 21 May 2009 10:29:11 PDT -07:00 
1.9.3p286 > t.appointment_time.in_time_zone # No additional conversion because rails already converted it to PST
 => Thu, 21 May 2009 10:29:11 PDT -07:00 
1.9.3p286 > t.appointment_time_before_type_cast # The raw value in the database, stored as UTC
 => "2009-05-21 17:29:11.614345" 
1.9.3p286 > t.appointment_time.utc
 => 2009-05-21 17:29:11 UTC 
1.9.3p286 > t.appointment_time = Time.parse("12:34:56") # Set the time in the server local timezone, i.e. EST
 => 2013-11-12 12:34:56 -0500 
1.9.3p286 > t.appointment_time # Reading the time. Note it's converted to PST already
 => Tue, 12 Nov 2013 09:34:56 PST -08:00 
1.9.3p286 > t.appointment_time.zone
 => "PST" 
1.9.3p286 > t.appointment_time.utc
 => 2013-11-12 17:34:56 UTC 
1.9.3p286 > t.save
 => true 
1.9.3p286 > t.reload
 => #<TripTicket ...> 
1.9.3p286 > t.appointment_time_before_type_cast
 => "2013-11-12 17:34:56" 

【讨论】:

  • PS:我是通过你的 saltlakecity.craigslist.org 帖子找到的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多