【问题标题】:Rails: how to create Time object in specific time zoneRails:如何在特定时区创建时间对象
【发布时间】:2012-05-04 09:33:52
【问题描述】:

我的应用在“莫斯科”(+04:00) 时区运行。但有时我只需要按当地时间(例如“2012 年 5 月 1 日 13:45”)和 ActiveSupport::TimeZone 对象的名称(例如“柏林”:夏令时 +02:00 和 +01: 00 否则)。

例如,如果我得到“2012 年 5 月 1 日 13:45”和“柏林”作为输入,我想产生“2012-05-01 13:45:00 +0200”或“2012-05-01 11:45” :00 +0000”。我创建以下函数:

def from_local_datetime(local_datetime, time_zone)
  offset = Time.now.in_time_zone(time_zone).formatted_offset
  datetime = case local_datetime
  when String
    DateTime.parse(local_datetime)
  else
    DateTime.new(local_datetime)
  end.change(:offset => offset)

  return datetime
end

乍一看,它按我的预期工作。但它是此类任务的最佳实践吗?可能在某些情况下它适用于错误。我不确定。

我会非常感谢任何 cmets。

UPD:我认为在 DST 更改时间时可能会出现错误。例如,2011 年 3 月 26 日是柏林时区的 GMT+1,Time.now.in_time_zone("Berlin").formatted_offset 返回“GMT+1”,但在 2011 年 3 月 27 日将是 GMT+2。因此,如果我在 3 月 27 日之前致电 from_local_datetime("28 march 2011", "Berlin"),它会返回 @987654324 @,但是如果我在更改函数返回时间后调用它28 march 2011 00:00:00 +0200 :(

【问题讨论】:

  • 我不理解这个错误。柏林在标准时间(冬季)是 UTC/(GMT) +1。也就是说,当格林威治/巴黎正午时,柏林已经是 13:00。在夏季,柏林人将时钟设置在标准时间之前,因此当 UTC 或格林威治标准时间为中午时,柏林的时间为 14:00。
  • 正如您从上面的代码中看到的那样,我通过以下代码获得柏林时区的当前偏移量:Time.now.in_time_zone(time_zone).formatted_offset(如果 Time.now 是 27 march 2011,则 +1)。但是当有28 march 2011(偏移量将是+2)时,我需要在柏林抵消。

标签: ruby-on-rails ruby datetime timezone tzinfo


【解决方案1】:

您的转换方法是正确的方法。

对于网站,您应确保将时间以 UTC 格式存储在数据库中。如果您可以从数据库中获取 UTC 值,而不是本地时间(或者您可以将 Web 服务器的时区设置为 UTC),那么您在去的时候就不必将时间从 UTC 转换为本地时间然后将其转换为用户的时区。

当然,您还必须存储用户的时区偏好。

【讨论】:

  • 请参阅原始问题中的更新
【解决方案2】:
TZInfo::Timezone.get('Europe/London')

查找时区

http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    相关资源
    最近更新 更多