2013-03-21 9 views
9

Potrzebuję tworzyć logi miesięcznie przez szereg miesięcy. Dlatego potrzebuję wszystkich [roku, miesiąca] krotek w danym zakresieUtwórz zakres miesięcy między dwiema datami ruby ​​

Jak przeprowadzasz iterację po datach?

Jak można tego dokonać, gdybym musiał codziennie wykonywać iteracje?

+0

Na co warto , jeśli masz dostęp do "ActiveSupport" w swoim projekcie, 'Range' może być po prostu rozszerzony do pracy ze zmiennymi krokami ze wsparciem strefy czasowej (zobacz http://stackoverflow.com/questions/19093487/ruby-create-range-of -dates/19094504 # answer-19094504). – captainpete

Odpowiedz

0

wymyśliłem tego rozwiązania, aby wygenerować listę wszystkich [rok, miesiąc] krotek w zakresie:

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

To jest całkiem niezłe, ale nie ładnie rozciągają się na dni jako miesiące, nie wszystkie mają ten sam zestaw dni co lata do miesięcy. – dbenhur

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 

Albo zaczyna swój miesiąc/rok krotek:

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

Użyj metody upto od daty: http://ruby-doc.org/stdlib-2.0/libdoc/date/rdoc/Date.html#method-i-upto

+0

Jak to pomaga OP iterować przez miesiące? – dbenhur

+1

Również twój blok arg i oświadczenie nie zgadzają się co do nazwy elementu, który uzyskał. – dbenhur

+0

Dlaczego wywołać 'Time.new.to_date' zamiast' Date.new' bezpośrednio? – dbenhur

2

Ruby Date obsługuje produkcję kolejne dni i oferuje metodę next_month, która może być użyta do wydajnego iterowania przez miesiące.

Oto ogólna metoda, która dopasowuje się do precyzji swoimi wejściami:

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

Na przykład:

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

"NoMethodError: niezdefiniowana metoda" today "dla Date: Class" chyba że "potrzebujesz" date'' – dbenhur

+2

Nie wiesz, dlaczego uważasz to za snarka. Wiele osób jest zaskoczonych tym, że w klasie 'irb' lub' pry' jest wbudowana klasa 'Date', która jest sparaliżowanym cieniem" Date ", które dostajesz po" wymaganiu "daty", a doktorzy robią okropną robotę informujący o konieczności stdlib. – dbenhur

0

Oto sposób napisałem, aby rozwiązać ten problem. Ten został zaprojektowany do pracy z danymi haskimi, takimi jak: {Niedziela, 01 stycznia 2012 => 58, środa, 01 lutego 2012 => 0, czw., 01 marca 2012 => 0} , ale można je łatwo zmodyfikować dla danych tablicowych.

Patrz: https://github.com/StephenOTT/add_missing_dates_ruby gdzie mam dostarczył próbkę kodu roboczego

ale klucz kawałek kodu jest:

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 

Kluczem treść patrzeć na to: (x+1.month).upto(datesHash.keys[count+1]-1.month)

Powiązane problemy