0

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

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

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

似乎有一个集合(空白 datetime_select)、一个保存(作为 UTC 存储在 db 中)、一个显示(<%= obj.date.to_utc %> 和一个修改(预填充的 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。

4

1 回答 1

0

您需要在您的应用程序中使用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" 
于 2013-11-08T14:19:56.647 回答