2011-06-27 30 views
8

我知道有几十个类似的问题在那里,更何况在Interwebs一般无数的文章,但我仍然有一个很难理解如何使用Rails的工作时间区域内部。帮助Rails中所著的Grokking时间和时区的3

目前,我有我的应用程序文件中配置config.time_zone = 'Eastern Time (US & Canada)',因为那是我和其他的项目管理员。拥有该网站的公司位于加利福尼亚州,因此它们将处于太平洋时间。该应用程序有全球受众,虽然我们还没有这样做,但我们最终将实现用户首选时区。

所以我目前的问题:

  1. 我知道存储并分别检索时,但什么是查看特定日期时间属性的本地版本的正确方法Rails的魔术般地变换日期时间列的值,并从UTC ?

  2. 当将一个使用Time.nowTime.zone.nowTime.now.in_time_zoneDateTime.nowDateTime.now.in_time_zone

  3. 什么是比较与其他一些相对于当前配置的时区特定的时间上面所列的方法或给定datetime属性的正确方法?使用UTC?

  4. 我们会有一些时间敏感的东西一样,需要根据应用程序的时区在特定时间对外公布,如何使应用程序的文章做到这一点,而不是到目前在我们指定的时区的比较配置一个(假定时区实现用户?)

  5. 新问题),如果我在以后的日子改变config.time_zoneUTC会发生什么?我是否必须重置数据库中的所有时间,否则会影响旧时代?

+0

这是一个很好的问题;我还没有找到关于正确实施时区的优秀文档。我会在列表中增加两个问题:'6。 Rails是否对夏令时很敏感和/或你如何实现敏感的时区支持?'和'7。 “对于日期列与日期时间列,Rails如何处理时区和DST有什么区别?'也许''8。这个数据库是不可知的,还是需要以不同的方式处理SQLite vs. MySQL与其他数据库? – Clay

+0

@Clay:你能找到关于这些问题的更多信息吗?我仍然在寻找关于这个主题的更多信息。 –

+0

我还没有找到太多好的信息。使用时区很容易成为我正在使用的爱好应用程序中最令人沮丧且耗时的部分。有一个很好的答复,我问这个问题:http://stackoverflow.com/questions/8466903/rails-3-1-querying-postgres-for-records-within-a-time-range但它只是相关的Postgres的。 – Clay

回答

8

首先,重要的是要明白,rails的时区主要是关于表示。在幕后,一切都在UTC发生。

Q1。在控制台Rails会显示次你默认的时区,所以Something.last.created_at显示,在由Time.zone

Q2给出的带时间戳。所有这些都会返回一个代表'now'的对象。 DateTime与Time的选择与时区无关。例如,如果您需要能够表示unix时代以外的时间,请使用DateTime。 Time.nowTime.zone.now之间的区别在于您是否取回Time的实例(它将作为控制器的本地时区)。该控制例如什么to_s回报,但不是即时的时间表示:

SomeModel.create(:time_attribute => Time.now) 
SomeModel.create(:time_attribute => Time.zone.now) 

将插入相同的行到数据库中。如果您只是向用户显示时间(例如,如果您的网站在标题中显示当前时间),那么您应该使用Time.zone.now,以便它显示在正确的时区中。如果你只是将它存储在数据库中,那么它并不重要 - activerecord无论如何都会将它转换为TimeWithZone。

Q3。TimeWithZone上的比较方法是通过比较日期的utc版本来实现的,因此您可以安全地比较不同区域中的时间 - 您无需将它们转换为某个常见时区。您还可以将TimeWithZone实例与纯时间对象进行比较。

Q4。你通常不需要做任何事情。实现此目的的常用方法是在模型上具有published_at属性。显示列表文章的页面将向查询添加

where('published_at <= ?', Time.now) 

条件。在创建文章时,Rails从表单中获取日期时间并将其转换为utc,因此数据库中存储的是该时间的utc版本。比较是独立的时区,所以无论时区是什么,查询都可以正常工作。

由于时区转换只能在您知道日期时才能正确完成(即您知道时间的精确时刻),因此可能会因日间时间的纯粹时间而变得复杂(例如'4pm'),具体取决于DST(或类似改变其时区的国家等政治事件)与UTC变化的偏差。在这种情况下,您通常只需要存储一天中的时间,并且只在尽可能晚的时候将其转换为全时,当您知道日期时。 Q30。

Q5。 Rails总是在数据库中存储UTC。这样做的直接后果是更改config.time_zone不需要您更改存储在数据库中的数据。您甚至可以在每个用户的基础上设置Time.zone,以便用户在其时区中看到时间 - config.time_zone只是控制Time.zone的默认值

+0

非常全面的解释。谢谢。 –

+0

我一直对此感到困惑,你的回答非常棒。 –