【问题标题】:Finding records across time zones using active record使用活动记录跨时区查找记录
【发布时间】:2014-05-17 17:40:30
【问题描述】:

我正在开发一个应用程序,用户可以在其中请求在其时区中每天的特定时间向他们发送一封电子邮件。 例如,用户 A 住在伦敦,并在伦敦时间每天下午 2 点安排一封电子邮件,而用户 B 住在纽约,并在纽约时间下午 2 点安排一封电子邮件。

我想知道我应该如何将我的时间表时间戳存储在我的数据库中,以及我需要存储哪些支持信息以支持所有时间都取决于特定时区这一事实。

我认为将时间戳存储为 utc 并为时区设置一个单独的列是可行的方法,但我不确定如何查询数据库以在特定时间返回所有预定的电子邮件而不必执行一个按时区查询。

【问题讨论】:

    标签: ruby-on-rails activerecord timezone


    【解决方案1】:

    是的,以 UTC 格式存储数据 - 默认情况下,rails 会这样做;在您的用户模型上放置一个time_zone 列

    这是我为 Rails 中的时区写的一篇文章,您可能会觉得有帮助:http://jessehouse.com/blog/2013/11/15/working-with-timezones-and-ruby-on-rails/

    这可能过于复杂,但我在想,如果你有一个后台作业正在运行(delayed_job、sidekiq 等),它会检查每个时区/电子邮件时间表 - 类似这样的事情(你肯定希望你的用户有 time_zone,也许在时间表?)

    # loop through all timezones
    ActiveSupport::TimeZone.zones_map(&:name).each do |time_zone|
      # get a list of any saved schedules in this timezone
      scheduled_in_zone = EmailSchedule.where(time_zone: time_zone)
    
      # execute block in that timezone
      Time.use_zone(time_zone) do 
        # Time.current is timezone aware (same as Time.zone.now)
        now = Time.current
    
        scheduled_in_zone.each do |scheduled|
          if scheduled.deliver_at <= now 
            scheduled.deliver_it!        
          end
        end
      end
    end
    

    我也建议查看:http://railscasts.com/episodes/106-time-zones-revised

    【讨论】:

    • 感谢您的回答。我不知道 use_zone 块,这真的很方便!我想避免的一件事是必须运行多个查询。随着表格大小的增加,这将变得非常痛苦。我希望能够运行一个查询,要求此时发送所有电子邮件,它会神奇地跨越所有时区。我在想可能没有办法通过活动记录来实现这一点,但我可能不得不下降到使用 postgres 中的时区支持并尝试在那里完成它。
    • 您还可以在每个时区拥有 1 个后台作业并同时运行它们;如果您将时区处理保留在 rails 中,则无需担心夏令时偏移
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多