我目前在我的应用程序文件中配置了config.time_zone =’Eastern Time(美国和加拿大)’,因为这是我和其他项目管理员所在的地方.拥有该网站的公司位于加利福尼亚州,因此他们将在太平洋时间.该应用程序拥有全球受众,虽然我们还没有这样做,但我们最终将实现用户首选时区.
那么我目前的问题:
>我知道Rails分别在存储和检索时会奇怪地将日期时间列值转换为UTC和从UTC转换,但是查看给定日期时间属性的本地版本的正确方法是什么?
>何时使用Time.now与Time.zone.now对Time.now.in_time_zone与DateTime.now对DateTime.now.in_time_zone?
>将给定的datetime属性与上面列出的方法或相对于当前配置的时区的某些其他特定时间进行比较的正确方法是什么?使用UTC?
>我们将有一些时间敏感的东西,比如需要根据应用程序的时区在特定时间发布的文章,那么如何让应用程序在我们指定的时区中进行比较而不是当前配置的时间(假设是否实现了用户时区?)
>(新问题)如果我以后将config.time_zone更改为UTC会怎样?我是否必须在数据库中重置所有时间,否则会影响旧时代?
解决方法
Q1.在控制台上,Rails将在您的默认时区中显示时间,因此Something.last.created_at会在Time.zone给出的区域中显示该时间戳
Q2.所有这些都返回一个代表’now’的对象. DateTime与时间的选择与时区无关.例如,如果您需要能够表示unix时期之外的时间,请使用DateTime. Time.now和Time.zone.now之间的区别在于您是否返回Time的实例(将在服务器的本地时区中作为控制器).这可以控制例如to_s返回的内容,但不控制表示的时刻:
SomeModel.create(:time_attribute => Time.now) SomeModel.create(:time_attribute => Time.zone.now)
将同一行插入数据库.如果您只是向用户显示时间(例如,如果您的站点显示标题中的当前时间),那么您应该使用Time.zone.now以便它以正确的时区显示.如果你只是将它存储在db中那么它并不重要 – activerecord无论如何都将它转换为TimeWithZone.
Q3. TimeWithZone上的比较方法是通过比较日期的utc版本来实现的,因此您可以安全地比较不同区域中的时间 – 您无需将它们转换为某个公共时区.您还可以将TimeWithZone实例与普通时间对象进行比较.
Q4.你通常不需要做任何事情.实现此目的的常用方法是在模型上使用published_at属性.显示列表文章的页面将添加一个
where('published_at <= ?',Time.now)
条件到查询.在创建文章时,Rails从表单中获取日期时间并将其转换为utc,因此存储在数据库中的是该published_at时间的utc版本.比较是时区独立的,因此无论时区是什么,查询都可以正常工作.
这可能会变得很复杂,只有一天中的纯时间(例如’4pm’),因为时区转换只有在您知道日期时才能正确完成(即您知道确切的时间点),这取决于DST(或政治)像国家/地区更改时区的事件)与UTC更改的偏移量.在这种情况下,您通常只想存储一天中的时间,并且只有在您知道日期时才将其转换为尽可能晚的全时.
Q5. Rails始终将UTC存储在数据库中.这样做的直接后果是更改config.time_zone不需要您更改存储在数据库中的数据.您甚至可以基于每个用户设置Time.zone,以便用户在其时区中查看时间 – config.time_zone只控制Time.zone的默认值
@H_403_12@ @H_403_12@