2012-05-04 45 views
4

我的应用在“莫斯科”(+04:00)时区工作。但有时我需要仅在当地时间创建时间对象(例如“01 May 2012 13:45”)和ActiveSupport :: TimeZone对象的名称(例如“柏林”:夏季+02:00和+01:否则为00)。Rails:如何在特定时区创建时间对象

例如,如果我得到“01 May 2012 13:45”和“Berlin”作为输入,我想要产生“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 

而在第一次看,它的工作原理与我的预期。但这是这种任务的最佳做法吗?可能在某些情况下它有错误。我不确定。

我对任何评论都很感激。

UPD:我认为当DST改变时间时可能会出现错误。例如2011年3月26日是格林威治标准时间+ 1在柏林时区和Time.now.in_time_zone("Berlin").formatted_offset返回“格林威治标准时间+1”,但它将在2011年3月27日格林威治标准时间+2。因此,如果我在3月27日之前致电from_local_datetime("28 march 2011", "Berlin")它返回28 march 2011 00:00:00 +0100,但如果我打电话它改变时间后,我的函数返回28 march 2011 00:00:00 +0200 :(

+0

我不理解的错误。柏林标准时间(冬季)是UTC /(格林威治标准时间)+1。也就是说,当它在格林威治/巴黎的中午时,已经是柏林的13:00了。今年夏天,柏林人在标准时间之前设置时钟,所以在UTC或格林尼治标准时间的中午,柏林的时间是14:00。 –

+0

从上面的代码可以看到,我通过以下代码获得柏林时区的当前偏移量:'Time.now.in_time_zone(time_zone).formatted_offset'(+1,如果Time.now是2011年3月27日)。但是我需要在柏林抵消'2011年3月28日'(抵消将是+2)。 – petRUShka

回答

0

你的转换方法是正确的做法。

与网站,你应该确保时间存储在数据库中的UTC,如果你能得到UTC价值出数据库,而不是本地时间(或者,也许你可以设置你的Web服务器的时区为UTC),它不需要将时间从UTC转换到本地时间,当你打算将它转换为无论如何用户的时区。

而且,当然,您将不得不存储用户的时区首选项。

+0

请参阅原始静态更新 – petRUShka

0
TZInfo::Timezone.get('Europe/London') 

找到时区

http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html 
相关问题