LoginSignup
13
4

More than 5 years have passed since last update.

ActiveSupport::TimeWithZone を型変換せずにイテレートする

Last updated at Posted at 2016-07-28
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

悲しい :sob:

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

動く :neutral_face:

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

いい :blush:
けれど、TimeWithZoneRange って名前が微妙 :weary:

13
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4