Class: Periodoxical::Core

Inherits:
Object
  • Object
show all
Includes:
Helpers, Validation
Defined in:
lib/periodoxical.rb

Constant Summary

Constants included from Validation

Validation::VALID_DAYS_OF_WEEK

Instance Method Summary collapse

Methods included from Helpers

#date_object_from, #day_of_week_long_to_short, #deep_symbolize_keys, #overlap?

Methods included from Validation

#validate!

Constructor Details

#initialize(starting_from:, ending_at: nil, time_blocks: nil, day_of_week_time_blocks: nil, limit: nil, exclusion_dates: nil, exclusion_times: nil, time_zone: 'Etc/UTC', days_of_week: nil, nth_day_of_week_in_month: nil, days_of_month: nil, duration: nil, months: nil) ⇒ Core

Returns a new instance of Core.

Parameters:

  • time_zone (String) (defaults to: 'Etc/UTC')

    Ex: ‘America/Los_Angeles’, ‘America/Chicago’, TZInfo::DataTimezone#name from the tzinfo gem (github.com/tzinfo/tzinfo)

  • starting_from (Date, String)
  • ending_at (Date, String) (defaults to: nil)
  • time_blocks (Array<Hash>) (defaults to: nil)

    Ex: [

    {
      start_time: '9:00AM',
      end_time: '10:30PM'
    },
    {
      start_time: '2:00PM',
      end_time: '2:30PM'
    }
    

    ]

  • days_of_week (Array<String>, nil) (defaults to: nil)

    Days of the week to generate the times for, if nil, then times are generated for every day. Ex: %w(mon tue wed sat)

  • days_of_month (Array<Integer>, nil) (defaults to: nil)

    Days of month to generate times for. Ex: %w(5 10) - The 5th and 10th days of every month

  • months (Array<Integer>, nil) (defaults to: nil)

    Months as integers, where 1 = Jan, 12 = Dec

  • limit (Integer) (defaults to: nil)

    How many date times to generate. To be used when ‘ending_at` is nil.

  • exclusion_dates (Aray<String>) (defaults to: nil)

    Dates to be excluded when generating the time blocks Ex: [‘2024-06-10’, ‘2024-06-14’]

  • exclusion_times (Aray<Hash>) (defaults to: nil)

    Timeblocks to be excluded when generating the time blocks if there is conflict (ie. overlap) Ex: [

      {
        start: '2024-06-10T10:30:00-07:00',
        end: '2024-06-10T11:30:00-07:00'
      },
      {
        start: '2024-06-10T14:30:00-07:00',
        end: '2024-06-10T15:30:00-07:00'
      },
    ]
    
  • day_of_week_time_blocks (Hash<Array<Hash>>) (defaults to: nil)

    To be used when hours are different between days of the week Ex: {

    mon: [{ start_time: '10:15AM', end_time: '11:35AM' }, { start_time: '9:00AM' }, {end_time: '4:30PM'} ],
    tue: { start_time: '11:30PM', end_time: '12:00AM' },
    fri: { start_time: '7:00PM', end_time: '9:00PM' },
    

    }

  • duration (Integer) (defaults to: nil)

    Splits the time_blocks into this duration (in minutes). For example, if time_block is 9:00AM - 10:00AM, and duration is 20 minutes. It creates 3 timeblocks of:

    - 9:00AM - 9:20AM
    - 9:20AM - 9:40AM
    - 9:40AM - 10:00AM
    


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/periodoxical.rb', line 74

def initialize(
  starting_from:,
  ending_at: nil,
  time_blocks: nil,
  day_of_week_time_blocks: nil,
  limit: nil,
  exclusion_dates: nil,
  exclusion_times: nil,
  time_zone: 'Etc/UTC',
  days_of_week: nil,
  nth_day_of_week_in_month: nil,
  days_of_month: nil,
  duration: nil,
  months: nil
)

  @time_zone = TZInfo::Timezone.get(time_zone)
  if days_of_week.is_a?(Array)
    @days_of_week = deep_symbolize_keys(days_of_week)
  elsif days_of_week.is_a?(Hash)
    @days_of_week_with_alternations = deep_symbolize_keys(days_of_week)
  end
  @nth_day_of_week_in_month = deep_symbolize_keys(nth_day_of_week_in_month)
  @days_of_month = days_of_month
  @months = months
  @time_blocks = deep_symbolize_keys(time_blocks)
  @day_of_week_time_blocks = deep_symbolize_keys(day_of_week_time_blocks)
  @starting_from = date_object_from(starting_from)
  @ending_at = date_object_from(ending_at)
  @limit = limit

  if duration
    unless duration.is_a?(Integer)
      raise "duration must be an integer"
    else
      @duration = duration
    end
  end
  @exclusion_dates = if exclusion_dates && !exclusion_dates.empty?
                       exclusion_dates.map { |ed| Date.parse(ed) }
                     end
  @exclusion_times = if exclusion_times
                       deep_symbolize_keys(exclusion_times).map do |et|
                         { start: DateTime.parse(et[:start]), end: DateTime.parse(et[:end]) }
                       end
                     end
  validate!
end

Instance Method Details

#generateArray<Hash<DateTime>>

Returns Ex: [

{
  start: #<DateTime>,
  end: #<DateTime>,
},
{
  start: #<DateTime>,
  end: #<DateTime>,
},

].

Returns:

  • (Array<Hash<DateTime>>)

    Ex: [

    {
      start: #<DateTime>,
      end: #<DateTime>,
    },
    {
      start: #<DateTime>,
      end: #<DateTime>,
    },
    

    ]



134
135
136
137
138
139
140
141
142
143
# File 'lib/periodoxical.rb', line 134

def generate
  initialize_looping_variables!
  while @keep_generating
    if should_add_time_blocks_from_current_date?
      add_time_blocks_from_current_date!
    end
    advance_current_date_and_check_if_reached_end_date
  end
  @output
end