Skip to content

Instantly share code, notes, and snippets.

@mizoR
Created January 10, 2015 06:30
Show Gist options
  • Save mizoR/351c36eeb1282570d199 to your computer and use it in GitHub Desktop.
Save mizoR/351c36eeb1282570d199 to your computer and use it in GitHub Desktop.
Ruby で 月ごとに繰り返す
require 'date'
# 実際は ActiveSupport の機能をつかう
class Date
def beginning_of_month
self.class.new(self.year, self.month, 1)
end
end
class MonthlyEnumerator < Enumerator
def initialize(params = {})
from = (params[:from] || Date.today).beginning_of_month
to = params[:to] || Date.today
super() do |y|
loop do
break if from > to
y << from
from = from.next_month
end
end
end
end
start = Date.new(2013, 7, 20)
last = Date.new(2015, 1, 10)
enum = MonthlyEnumerator.new(from: start, to: last)
enum.each do |date|
puts date
end
__END__
$ ruby example.rb
2013-07-01
2013-08-01
2013-09-01
2013-10-01
2013-11-01
2013-12-01
2014-01-01
2014-02-01
2014-03-01
2014-04-01
2014-05-01
2014-06-01
2014-07-01
2014-08-01
2014-09-01
2014-10-01
2014-11-01
2014-12-01
2015-01-01
@mizoR
Copy link
Author

mizoR commented Jan 10, 2015

Enumerator なんで、当然 次のようなことも出来る

enum = MonthlyEnumerator.new(from: start, to: last)
enum.group_by {|date| date.year}.each do |year, months|
  puts "#{year} 年"
  months.each do |month|
    puts month
  end
end

# =>
2013 
2013-07-01
2013-08-01
2013-09-01
2013-10-01
2013-11-01
2013-12-01
2014 
2014-01-01
2014-02-01
2014-03-01
2014-04-01
2014-05-01
2014-06-01
2014-07-01
2014-08-01
2014-09-01
2014-10-01
2014-11-01
2014-12-01
2015 
2015-01-01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment