2013-03-21 55 views
9

我需要在一个月的范围内每个月创建一个日志文件。 因此,我需要给定范围内的所有[年,月]元组在红宝石的两个日期之间创建一个月的范围

如何迭代日期?

如果我需要每天迭代,这怎么办?

+0

对于它的价值,如果您有权访问项目中的'ActiveSupport''Range'可以简单地扩展为支持具有时区支持的变量步长(请参阅http://stackoverflow.com/questions/19093487/ruby-create-range-of -dates/19094504#答案-19094504)。 – captainpete 2013-11-01 00:52:35

回答

0

我想出了这个解决方案产生范围内的所有[年月]元组的列表:

first=[2012,10] 
last=[2013,03] 
(first[0]..last[0]).to_a.product((1..12).to_a).select{|ym|(first..last).cover?(ym)} 
=> [[2012, 10], [2012, 11], [2012, 12], [2013, 1], [2013, 2], [2013, 3]] 
+0

这很不错,但不会很好地延伸到几天,因为几个月并不都具有几年的几天相同的天数。 – dbenhur 2013-03-21 20:53:09

1
require 'date' 
Time.new(2011).to_date.upto(Time.now.to_date) do |a| 
    puts ""+a.day.to_s+","+a.month.to_s+","+a.year.to_s 
end 

或者让你的月/年的元组:

require 'date' 
result = [] 
Time.new(2002).to_date.upto(Time.now.to_date) do |a| 
    result << [a.month,a.year] 
end 
result.uniq! 

使用从日期开始的upto方法:http://ruby-doc.org/stdlib-2.0/libdoc/date/rdoc/Date.html#method-i-upto

+0

这是如何帮助OP按月迭代的? – dbenhur 2013-03-21 22:44:42

+1

此外,您的块arg和放置语句不同意有关元素的名称。 – dbenhur 2013-03-21 22:45:37

+0

为什么直接调用'Time.new.to_date'而不是'Date.new'? – dbenhur 2013-03-21 22:47:15

2

红宝石Date支持生产连续几天,并提供一个next_month方法,可用于有效地迭代数月。

下面是适应你的输入精度的一般方法:

require 'date' 

def date_tuples(from,to) 
    prec = from.size 
    start = Date.new(*from) 
    finish = Date.new(*to) 

    filter_on = [:day,:mon].first(3-prec) 
    filter = ->(d) { filter_on.all? {|attr| d.send(attr) == 1 } } 

    (start..finish) 
    .select(&filter) 
    .map { |d| [d.year,d.mon,d.day].first(prec) } 
end 

[7] pry(main)> date_tuples([2012],[2015]) 
=> [[2012], [2013], [2014], [2015]] 
[8] pry(main)> date_tuples([2012,10],[2013,3]) 
=> [[2012, 10], [2012, 11], [2012, 12], [2013, 1], [2013, 2], [2013, 3]] 
[9] pry(main)> date_tuples([2012,10,25],[2012,11,6]) 
=> [[2012, 10, 25], 
[2012, 10, 26], 
[2012, 10, 27], 
[2012, 10, 28], 
[2012, 10, 29], 
[2012, 10, 30], 
[2012, 10, 31], 
[2012, 11, 1], 
[2012, 11, 2], 
[2012, 11, 3], 
[2012, 11, 4], 
[2012, 11, 5], 
[2012, 11, 6]] 
25

例如:

((Date.today - 90)..Date.today).map{|d| [d.year, d.month]}.uniq 
#=> [[2012, 12], [2013, 1], [2013, 2], [2013, 3]] 
+1

“NoMethodError:未定义的方法'今日'为日期:类”除非你'需要'日期'' – dbenhur 2013-03-22 06:03:55

+2

不知道你为什么认为这个snark。很多人都惊讶于'irb'或'pry'开箱的'Date'类内置了'Date'类,这是'require'date'后得到的'Date'的残影,文档做了一件糟糕的工作告诉你何时需要从stdlib请求。 – dbenhur 2013-03-22 15:13:28

0

这里是一个方式,我写来解决这个问题。 这是专为处理哈希数据,如: {太阳,2012年1月1日=> 58,2012年3月1日星期三=> 0,星期四,2012年3月01日=> 0} 但可以很容易地修改阵列数据。

参见:https://github.com/StephenOTT/add_missing_dates_ruby这里我提供了一个工作代码示例

但是代码的关键部分是:

def addMissingMonths (datesHash) 
    count = 0 
    result = {} 

    datesHash.keys.each do |x| 
     if x != datesHash.keys.last 
      (x+1.month).upto(datesHash.keys[count+1]-1.month) do |a| 
       result[a.at_beginning_of_month] = 0 
      end 
     end 

     count += 1 
    end 

    return result.merge!(datesHash) 
end 

的关键内容,在就是看:(x+1.month).upto(datesHash.keys[count+1]-1.month)