【问题标题】:Rails AR Date Range Query - Daylight Saving - OverlapRails AR 日期范围查询 - 夏令时 - 重叠
【发布时间】:2018-05-01 08:20:23
【问题描述】:

我有一个 Rails 3 应用程序,如何避免由于夏令时而发生重叠?

我的问题是我有一个生成报告的表单。审计不一致时,我注意到在 3 月 11 日结束的那一周出现的一堆交易也出现在 3 月 12 日开始的那一周。

问题归结为这样的事情......

Time.zone.parse('2018-03-11').to_datetime.end_of_day.utc
 => Mon, 12 Mar 2018 07:59:59 +0000 
Time.zone.parse('2018-03-12').to_datetime.beginning_of_day.utc
 => Mon, 12 Mar 2018 07:00:00 +0000 

上面的 1 小时重叠似乎是我的问题所在。检查日期范围时(请参阅下面的实际代码)如何避免这种重叠。

实际代码

这是类似于按日期过滤的实际代码。

  scope :filter_date, lambda { |starts, ends, date, transaction_type = :transaction|
    _scope = scoped


    starts = Time.zone.parse(starts).to_datetime        if starts.class == String and starts.present?
    ends   = Time.zone.parse(ends).to_datetime.tomorrow if ends.class   == String and ends.present?

    begin
      case date
      when 'settled'
        transaction_type == "batch" ? date_field = 'deposited_at' : date_field = 'settled_at'
        _scope = _scope.order('transactions.'+date_field+' DESC')
        _scope = _scope.where("transactions."+date_field+" >= ?", starts) if starts.present?
        _scope = _scope.where("transactions."+date_field+" < ?", ends)   if ends.present?
      else # created, nil, other
        _scope = _scope.order('transactions.created_at DESC')
        _scope = _scope.where("transactions.created_at >= ?", starts) if starts.present?
        _scope = _scope.where("transactions.created_at < ?", ends)   if ends.present?
      end
    end
    _scope
  }

堆栈

  • Ruby 2.1
  • Rails 3.2
  • PG

问题

如何克服夏令时生效的时间重叠。

【问题讨论】:

  • 为什么你认为你真的需要对它做任何事情?您应该记住,这不是您的代码中的错误。这是世界本身的一个错误。从概念的角度来看,这些交易确实发生在两个星期内:(如果您仍然绝对确定我们需要对其进行处理,那么我将跟进一些解决方案
  • @AntonTkachov 我不知道这是一件事,直到来自帐户的人提出每周报告与生成的报告不一致的标志。总结的周报与月报不同。
  • 我认为讨论他们如何处理这些差异是有意义的。向他们描述一个问题,并获得一些关于他们对可能解决方案的看法的反馈。因为您的代码工作正常且绝对合乎逻辑。同时我会考虑一些技巧,如何处理这个:)
  • 写了一个解决方案。我希望你能及时通知我
  • 我的回答对你有帮助吗?

标签: ruby-on-rails ruby postgresql ruby-on-rails-3 activerecord


【解决方案1】:

试试这个解决方案。我认为它应该可以解决您的问题:

scope :filter_date, lambda { |starts, ends, date, transaction_type = :transaction|
  _scope = scoped

  if starts.class == String and starts.present?
    starts = Time.zone.parse(starts)
    starts += 1.hour if starts.dst?
    starts = starts.to_datetime
  end

  if ends.class == String and ends.present?      
    ends = Time.zone.parse(ends) + 1.day
    ends += 1.hour if ends.dst?
    ends = ends.to_datetime
  end

  begin
    case date
    when 'settled'
      transaction_type == "batch" ? date_field = 'deposited_at' : date_field = 'settled_at'
      _scope = _scope.order('transactions.'+date_field+' DESC')
      _scope = _scope.where("transactions."+date_field+" >= ?", starts) if starts.present?
      _scope = _scope.where("transactions."+date_field+" < ?", ends)   if ends.present?
    else # created, nil, other
      _scope = _scope.order('transactions.created_at DESC')
      _scope = _scope.where("transactions.created_at >= ?", starts) if starts.present?
      _scope = _scope.where("transactions.created_at < ?", ends)   if ends.present?
    end
  end
  _scope
}

【讨论】:

  • @Ziyan Junaideen 这对你有帮助吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2018-03-03
  • 1970-01-01
  • 2015-01-22
  • 1970-01-01
  • 2012-09-28
  • 2010-10-16
相关资源
最近更新 更多