ruby 我怎样才能循环通过一个具有不同间隔的数据范围?

vc6uscn9  于 2023-01-30  发布在  Ruby
关注(0)|答案(5)|浏览(120)

我有一个日期范围(从,到),我想通过不同的间隔(每天,每周,每月,...)循环
我怎样才能循环这个数据范围?

  • 最新情况 *

谢谢你的回答,我想出了以下:

interval = 'week' # month, year
start = from
while start < to
  stop  = start.send("end_of_#{interval}")
  if stop > to
    stop = to
  end
  logger.debug "Interval from #{start.inspect} to #{stop.inspect}"
  start = stop.send("beginning_of_#{interval}")
  start += 1.send(interval)
end

这将以周、月或年为间隔遍历日期范围,并考虑给定间隔的开始和结束。
由于我没有在我的问题中提到这一点,我选择了把我推向正确方向的答案。

llew8vvj

llew8vvj1#

是否循环,直到from日期加上1.day1.week1.month大于to日期?

> from = Time.now
 => 2012-05-12 09:21:24 -0400 
 > to = Time.now + 1.month + 2.week + 3.day
 => 2012-06-29 09:21:34 -0400 
 > tmp = from
 => 2012-05-12 09:21:24 -0400 
 > begin
?>   tmp += 1.week
?>   puts tmp
?> end while tmp <= to
2012-05-19 09:21:24 -0400
2012-05-26 09:21:24 -0400
2012-06-02 09:21:24 -0400
2012-06-09 09:21:24 -0400
2012-06-16 09:21:24 -0400
2012-06-23 09:21:24 -0400
2012-06-30 09:21:24 -0400
 => nil
fcwjkofz

fcwjkofz2#

在Ruby 1.9中,我在Range上添加了自己的方法,用于遍历时间范围:

class Range
  def time_step(step, &block)
    return enum_for(:time_step, step) unless block_given?

    start_time, end_time = first, last
    begin
      yield(start_time)
    end while (start_time += step) <= end_time
  end
end

然后,你可以这样调用它,例如(我的例子使用了一个Rails特有的方法:15分钟):

irb(main):001:0> (1.hour.ago..Time.current).time_step(15.minutes) { |time| puts time }
2012-07-01 21:07:48 -0400
2012-07-01 21:22:48 -0400
2012-07-01 21:37:48 -0400
2012-07-01 21:52:48 -0400
2012-07-01 22:07:48 -0400
=> nil

irb(main):002:0> (1.hour.ago..Time.current).time_step(15.minutes).map { |time| time.to_s(:short) }
=> ["01 Jul 21:10", "01 Jul 21:25", "01 Jul 21:40", "01 Jul 21:55", "01 Jul 22:10"]

注意,这个方法使用了Ruby1.9的约定,如果没有给定代码块,枚举方法返回一个枚举数,这样就可以将枚举数串在一起。

更新

我已经将Range #time_step方法添加到my personal core_extensions "gem"中,如果您想在Rails项目中使用它,只需将以下代码添加到Gemfile中:

gem 'core_extensions', github: 'pdobb/core_extensions'
nqwrtyyt

nqwrtyyt3#

succ方法在1.9范围内被弃用。想在一周内做同样的事情,我得出了这个解决方案:

def by_week(start_date, number_of_weeks)
    number_of_weeks.times.inject([]) { |memo, w| memo << start_date + w.weeks }
  end

返回间隔中周的数组.很容易适应月.

1sbrub3j

1sbrub3j4#

您可以在Range对象上使用step方法。http://ruby-doc.org/core-1.9.3/Range.html#method-i-step

2q5ifsrm

2q5ifsrm5#

想想时间戳,它们是普通的整数,你可以对它们使用基本的算术。我的解决方案是在时间戳的帮助下创建数组。

start_date = Time.now.to_datetime
end_date = Time.now.to_datetime + 1.year
interval = 10.years.in_days.to_i.days.in_seconds
# To make the first date as start date
epoch = start_date.to_i - interval

(start_date..end_date)
  .select {|time| (time.to_i - epoch) % interval == 0 }
  .each { |time| puts time }

相关问题