2013-03-21 58 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)