from = Time.zone.parse('2016/07/25 12:30:00')
to = Time.zone.parse('2016/07/31 12:30:00')
そのまま
(from..to).each.with_index(1) { |t, i| puts("#{i} 日目: #{t}") }
TypeError: can't iterate from ActiveSupport::TimeWithZone
悲しい
DateTime に変換する
(from.to_datetime..to.to_datetime).each.with_index(1) { |t, i| puts("#{i} 日目: #{t}") }
1 日目: 2016-07-25T12:30:00+09:00
2 日目: 2016-07-26T12:30:00+09:00
3 日目: 2016-07-27T12:30:00+09:00
4 日目: 2016-07-28T12:30:00+09:00
5 日目: 2016-07-29T12:30:00+09:00
6 日目: 2016-07-30T12:30:00+09:00
7 日目: 2016-07-31T12:30:00+09:00
動く
ActiveSupport::TimeWithZone のまま頑張るぞい!
class TimeWithZoneRange
include Enumerable
def initialize(range, interval=1.day)
@range = range
@interval = interval
@from = range.first
@to = range.last
end
def each
return enum_for(:each) unless block_given?
time_with_zone = @from
loop do
yield(time_with_zone)
time_with_zone = time_with_zone.since(@interval)
next if cover_last? && time_with_zone == @to
break unless time_with_zone < @to
end
self
end
private
def cover_last?
@range.cover?(@to)
end
end
TimeWithZoneRange.new(from..to).each.with_index(1) { |t, i| puts("#{i} 日目: #{t}") }
1 日目: 2016-07-25 12:30:00 +0900
2 日目: 2016-07-26 12:30:00 +0900
3 日目: 2016-07-27 12:30:00 +0900
4 日目: 2016-07-28 12:30:00 +0900
5 日目: 2016-07-29 12:30:00 +0900
6 日目: 2016-07-30 12:30:00 +0900
7 日目: 2016-07-31 12:30:00 +0900
TimeWithZoneRange.new(from...to).each.with_index(1) { |t, i| puts("#{i} 日目: #{t}") }
1 日目: 2016-07-25 12:30:00 +0900
2 日目: 2016-07-26 12:30:00 +0900
3 日目: 2016-07-27 12:30:00 +0900
4 日目: 2016-07-28 12:30:00 +0900
5 日目: 2016-07-29 12:30:00 +0900
6 日目: 2016-07-30 12:30:00 +0900
いい
けれど、TimeWithZoneRange って名前が微妙