Sha256: 89f9771caf985a76852c71daf076a83bee8a4f348c0b673b1aa863833f50d782

Contents?: true

Size: 1.43 KB

Versions: 1

Compression:

Stored size: 1.43 KB

Contents

# typed: strict
module Repeatable
  module Expression
    class WeekdayInMonth < Date
      include LastDateOfMonth

      sig { params(weekday: Integer, count: Integer).void }
      def initialize(weekday:, count:)
        @weekday = weekday
        @count = count
      end

      sig { override.params(date: ::Date).returns(T::Boolean) }
      def include?(date)
        day_matches?(date) && week_matches?(date)
      end

      private

      sig { returns(Integer) }
      attr_reader :weekday

      sig { returns(Integer) }
      attr_reader :count

      sig { params(date: ::Date).returns(T::Boolean) }
      def day_matches?(date)
        date.wday == weekday
      end

      sig { params(date: ::Date).returns(T::Boolean) }
      def week_matches?(date)
        if negative_count?
          week_from_end(date) == count
        else
          week_from_beginning(date) == count
        end
      end

      sig { params(date: ::Date).returns(Integer) }
      def week_from_beginning(date)
        week_in_month(date.day - 1)
      end

      sig { params(date: ::Date).returns(Integer) }
      def week_from_end(date)
        -week_in_month(last_date_of_month(date).day - date.day)
      end

      sig { params(zero_indexed_day: Integer).returns(Integer) }
      def week_in_month(zero_indexed_day)
        (zero_indexed_day / 7) + 1
      end

      sig { returns(T::Boolean) }
      def negative_count?
        count < 0
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
repeatable-1.1.0 lib/repeatable/expression/weekday_in_month.rb