Rails AR Запрос диапазона дат - переход на летнее время - перекрытие - PullRequest
0 голосов
/ 01 мая 2018

У меня есть приложение на Rails 3, как избежать дублирования из-за перехода на летнее время?

Моя проблема в том, что у меня есть форма для создания отчетов. Проверяя несоответствие, я заметил, что несколько транзакций отображаются на неделе, заканчивающейся 11 марта, также на неделе, начинающейся 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
  }

Stack

  • Рубин 2,1
  • Рельсы 3,2
  • PG

Вопрос

Как я могу преодолеть это перекрытие времени, когда вступает в силу летнее время.

1 Ответ

0 голосов
/ 02 мая 2018

Попробуйте это решение. Я думаю, что это должно решить вашу проблему:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...