Activerecord:将字符串转换为本地时间

发布于 2024-11-14 07:15:37 字数 434 浏览 0 评论 0原文

我读了很多文章,做了功课。我将所有时间存储为 UTC,每个用户设置自己的时区等。这是我遇到的问题:

Time.zone
=> GMT-05:00 Eastern Time US  Canada

t = Ticket.first
t.hold_until = "Jan 1, 2012 9:00PM"
t.save!

t.hold_until
=> Sun, 01 Jan 2012 16:00:00 EST -05:00

# notice the above time lost 5 hours

问题是该字符串来自用户提供的 POST 请求。假设用户输入是本地时间而不是 UTC,这不是最有意义的吗?我是否遗漏了某些内容,或者这不应该是 ActiveRecord 默认值?除了必须转换我所有控制器中的时间之外,执行此操作的正确方法是什么?这似乎是错误的,而且不是很干。

I've read quite a few articles, done my homework. I have all times stored as UTC, each user sets their own time zone, etc. Here's the problem I'm having:

Time.zone
=> GMT-05:00 Eastern Time US  Canada

t = Ticket.first
t.hold_until = "Jan 1, 2012 9:00PM"
t.save!

t.hold_until
=> Sun, 01 Jan 2012 16:00:00 EST -05:00

# notice the above time lost 5 hours

The issue is that the string is from a POST request supplied by the user. Doesn't it make the most sense to assume user input is in their local time, not UTC. Am I missing something or shouldn't that be the ActiveRecord default? Whats the proper way to do this, beyond having to convert the time in all of my controllers. That just seems wrong and not very DRY.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彩虹直至黑白 2024-11-21 07:15:37

我发现了这个问题,它与 ActiveRecord 中编写得不​​好的代码有关(惊讶!)。无论如何,ActiveRecord::Base.define_attribute_methods 通过方法缺失被延迟调用。我这样定义了这个方法:

def hold_until=(value)
  # do some stuff here
  super
end

因此 ActiveRecord 会跳过该方法,认为它已定义。这应该不重要,但由于设计不佳,它确实如此。 AR 有多种不同的方式来根据列类型定义方法。调用 super side 会执行此操作并直接进行一般的“write_attribute”调用。唯一的解决办法就是自己转换时间。由于所有alias_method_chain的废话,在包含模块之前你不能调用define_attribute_methods。而且您无法利用他们已经编写的代码,因为它位于 class_eval 块中。如果可能的话,我会推荐 datamapper。

I figured out the issue and it has to do with poorly written code within ActiveRecord (surprise!). Anyways, ActiveRecord::Base.define_attribute_methods gets called lazily via method missing. I had this method defined like so:

def hold_until=(value)
  # do some stuff here
  super
end

So ActiveRecord was skipping that method thinking it was defined. It shouldn't matter, but due to poor design it does. AR has a variety of different ways to define methods based on their column type. Calling super side steps this and goes right to a general "write_attribute" call. The only solution is to convert the time yourself. You can't call define_attribute_methods before you include the modules because of all the alias_method_chain bullshit. And you can't leverage the code they've already written because its in a class_eval block. I would recommend datamapper if at all possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文