在Rails 3中将UTC转换为本地时间

104

我在Rails 3中将UTC TimeTimeWithZone转换为本地时间遇到了问题。

假设moment是一个UTC时间的Time变量(例如moment = Time.now.utc)。如何将moment转换为我的时区,并处理夏令时(即使用EST / EDT)?

更确切地说,如果时间对应于今天早上9点EDT,则我想要输出"星期一,3月14日,上午9点",如果时间是上周一早上9点EST,则输出"星期一,3月7日,上午9点"。

希望还有其他方法?

编辑:我最初认为"EDT"应该是一个被认可的时区,但"EDT"不是一个实际的时区,而更像是时区的状态。例如,询问Time.utc(2011,1,1).in_time_zone("EDT")没有任何意义。这有点令人困惑,因为"EST"一个实际的时区,在一些不使用夏令时并且全年都是(UTC-5)的地方使用。

6个回答

132

Time#localtime会给你当前运行代码的机器所在时区的时间:

> moment = Time.now.utc
  => 2011-03-14 15:15:58 UTC 
> moment.localtime
  => 2011-03-14 08:15:58 -0700 

更新:如果你想将时间转换成特定的时区而不是你自己的时区,你已经在正确的轨道上了。但是,不要担心东部标准时间(EST)和东部夏令时(EDT),只需传入一般的东部时区 -- 它会根据日期知道是否为EDT或EST:

> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
  => Mon, 14 Mar 2011 11:21:05 EDT -04:00 
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
  => Sat, 14 Jan 2012 10:21:18 EST -05:00 

这是一个开始。我该如何设置当前时区(因为我甚至不确定应用程序将托管在哪里,服务器可能位于不同的时区,那么应该使用什么时区)。 - Marc-André Lafortune
7
“localtime”方法很酷,但是代码运行的机器的时区并不像用户访问Web应用程序的时区那样有用。(如此处所述:https://dev59.com/c1fUa4cB1Zd3GeqPFjIK#6105487)你如何获取访问Web应用程序的用户的时区? - dmonopoly
@daze 我想你可以为你的用户设置一个选项来选择他们的时区,然后使用in_time_zone方法和他们的时区。 - Dylan Markow
1
谢谢,localtime方法正是我所需要的。 - Bob
Time.now.localtime 在普通的 irb 会话中可以运行,但是当我尝试在一个处于 UTC 时区的机器上运行它时,它无法工作。 - Ava
如果机器处于UTC时区,我猜用户期望的是UTC时间,对吗? - JohnMerlino

117

Rails有它自己的一些名词。使用以下代码查看它们:

rake time:zones:us

您还可以运行rake time:zones:all来获取所有时区。 要查看更多与时区相关的rake任务:rake -D time

因此,要自动适应夏令时并转换为东部标准时间(EST):

Time.now.in_time_zone("Eastern Time (US & Canada)")

21
如何自动使用用户访问 web 应用程序的时区? - dmonopoly
我发现的唯一方法是使用Javascript,然后将其传回服务器。(new Date()).getTimeZoneOffset()。但它相当不一致,所以这个人似乎编写了自己的代码:http://www.onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/ - Duke
2
自动将时区添加到所有ActiveRecord日期时间 - config.time_zone ='Eastern Time(美国和加拿大)' - 在config / application.rb中。 - idrinkpabst
更新:链接JS解决方案的所有者指向了更新的解决方案:http://pellepim.bitbucket.org/jstz/ - Miles
@dmonopoly,您可以在应用程序配置中设置时区config.time_zone ='Wellington',然后使用Time.current(它等同于time.now,但使用您设置的时区)。 - Sean

18

使用系统本地时区进行配置非常简单, 只需在您的application.rb文件中添加以下内容:

config.time_zone = Time.now.zone

然后,Rails 应该会把时间戳显示为您的本地时间,或者您可以使用类似这样的指令来获取本地时间

Post.created_at.localtime

15

这是最好的方法。我们已经知道了存储的时间,以我个人的观点,在客户端以最佳方式显示给用户是最好的做法,而这正是它所实现的。 - Neeraj Shukla

1
如果您只是想获取用户的时区,那么您需要做的就是在您的 config/applications.rb 文件中更改您的时区设置。
例如:
Rails默认会将您的时间记录保存为UTC时间,即使您指定了当前的时区。
config.time_zone = "Singapore"

所以这就是你需要做的,然后你就可以开始了。


1

我不知道为什么,但在我的情况下,它不像之前建议的那样工作。 但是它可以这样工作:

Time.now.change(offset: "-3000")

当然,您需要将offset值更改为您自己的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接