class Symian::WorkShift

Constants

Infinity

an infinitely large value

WORKSHIFT_24x7

24x7 work shift

WORKSHIFT_TABLE

the predefined work shift table

Public Class Methods

new(type, params={}) click to toggle source
# File lib/symian/work_shift.rb, line 4
def initialize(type, params={})
  case type
    when :predefined
      # get workshift id
      raise ArgumentError unless params[:id]
      wsid = params[:id]

      # retrieve predefined workshift
      predefined_workshift = WORKSHIFT_TABLE[wsid]
      raise ArgumentError unless predefined_workshift

      # load start_time and end_time from predefined workshift
      @start_time = predefined_workshift[:start_time]
      @end_time   = predefined_workshift[:end_time]
    when :custom
      # load start_time and end_time from parameters
      raise ArgumentError unless params[:start_time] and params[:end_time]
      @start_time = params[:start_time]
      @end_time   = params[:end_time]
    when :all_day_long
      # nothing to do
    else
      raise ArgumentError
  end

  # save work shift type
  @type = type

  unless @type == :all_day_long
    # normalize start_time and end_time by transforming them from
    # instances of (Date)Time class to integers representing the
    # number of seconds elapsed from last midnight UTC
    @start_time = @start_time.utc.seconds_since_midnight.round
    @end_time   = @end_time.utc.seconds_since_midnight.round
  end

  # check if it is an overnight work shift
  @overnight = (@type == :all_day_long ? false : @end_time < @start_time)
end

Public Instance Methods

active_at?(time) click to toggle source
# File lib/symian/work_shift.rb, line 45
def active_at?(time)
  return true if @type == :all_day_long

  t = time.utc.seconds_since_midnight.round
  if @overnight
    t <= @end_time or t >= @start_time
  else
    @start_time <= t and t <= @end_time
  end
end
duration() click to toggle source
# File lib/symian/work_shift.rb, line 106
def duration
  return Infinity if @type == :all_day_long

  res = if @overnight
    1.day.to_i - @start_time + @end_time
  else
    @end_time - @start_time
  end

  # need to convert to integer
  res.round
end
secs_to_begin_of_shift(time) click to toggle source
# File lib/symian/work_shift.rb, line 82
def secs_to_begin_of_shift(time)
  raise 'secs_to_begin_of_shift called for available operator' if active_at?(time)

  t = time.utc.seconds_since_midnight.round
  res = if @overnight
    # TODO: raise error if t < @end_time or t > @start_time
    raise 'Weirder error in secs_to_begin_of_shift!' if t < @end_time or t > @start_time
    @start_time - t
  else
    if t <= @start_time
      @start_time - t
    elsif t >= @end_time
      @start_time + 1.day - t
    else
      # TODO: else raise error
      raise 'Weird error in secs_to_begin_of_shift!'
    end
  end

  # need to convert to integer
  res.round
end
secs_to_end_of_shift(time) click to toggle source
# File lib/symian/work_shift.rb, line 57
def secs_to_end_of_shift(time)
  raise 'secs_to_end_of_shift called for unavailable operator' unless active_at?(time)
  return Infinity if @type == :all_day_long

  t = time.utc.seconds_since_midnight.round
  res = if @overnight
    if t <= @end_time
      @end_time - t
    elsif t >= @start_time
      @end_time + 1.day - t
    else
      # TODO: else raise error
      raise 'Weird error in secs_to_end_of_shift!'
    end
  else
    # TODO: raise error if t < @start_time or t > @end_time
    raise 'Weirder error in secs_to_end_of_shift!' if t < @start_time or t > @end_time
    @end_time - t
  end

  # need to convert to integer
  res.round
end