Skip to content

Instantly share code, notes, and snippets.

@msg7086 msg7086/Gemfile

Last active Oct 25, 2015
Embed
What would you like to do?
source 'https://rubygems.org'
gem 'activesupport'
gem 'rspec-rails'
require 'active_support'
require 'active_support/core_ext'
class Schedule
NO_REPEAT = 0
R_DAY = 1
R_WDAY = 2
R_WEEK = 3
R_MONTH = 4
EOL = 10.years.since
attr_accessor :current_start, :current_end
def initialize start_time:, end_time:, repeat: 0, last_time: nil
@start_time = start_time
@end_time = end_time
@repeat = repeat
@last_time = last_time
@current_start = @start_time
@current_end = @end_time
end
# return: nil if no next, else a schedule start from next date
def next_time!
return if @current_start.nil?
return @current_start = nil if @repeat == NO_REPEAT
offset = 0
case @repeat
when R_DAY then offset = 1.day
when R_WDAY then offset = @current_start.wday == 5 ? 3.days : 1.day
when R_WEEK then offset = 7.days
when R_MONTH then offset = find_next_month_offset
end
duration = @current_end - @current_start
@current_start += offset
@current_end = @current_start + duration
return @current_start = nil if @last_time && @current_start > @last_time
return @current_start = nil if @current_start > EOL
@current_start
end
# next month at the end of the month could be more than 1 month offset
# next month of 3/31 is 5/31
def find_next_month_offset
length = 0
this_month = @current_start
loop do
length += 1
next_month = this_month + length.months
break if next_month.day == this_month.day
end
length.month
end
def conflicts? sch
# @start within sch?
return true if @current_start >= sch.current_start && @current_start <= sch.current_end
# @end within sch?
return true if @current_end >= sch.current_start && @current_end <= sch.current_end
# @ contains sch?
return true if @current_start <= sch.current_start && @current_end >= sch.current_end
# safe
false
end
end
class ScheduleService
def self.conflicts? s1, s2
# if both schedule exists?
while !s1.current_start.nil? && !s2.current_start.nil?
# check if they conflicts
return true if s1.conflicts? s2
# find the next date to compare
if s1.current_start < s2.current_start
s1.next_time!
else
s2.next_time!
end
end
false
end
end
require './main'
describe Schedule do
it 'generates future events by month' do
t = Time.new(2015,1,31)
s = Schedule.new start_time: t, end_time: t + 40.minutes, repeat: 4, last_time: t + 1.year
tlist = []
while !s.current_start.nil? do
tlist << s.current_start
s.next_time!
end
expect(tlist.size).to eq 8
end
it 'generates future events by week' do
t = Time.new(2015,1,31)
s = Schedule.new start_time: t, end_time: t + 40.minutes, repeat: 3, last_time: t + 1.year
tlist = []
while !s.current_start.nil? do
tlist << s.current_start
s.next_time!
end
expect(tlist.size).to eq 53
end
it 'generates future events by workday' do
t = Time.new(2015,2,2) # It's monday
s = Schedule.new start_time: t, end_time: t + 40.minutes, repeat: 2, last_time: t + 1.month
tlist = []
while !s.current_start.nil? do
tlist << s.current_start
s.next_time!
end
expect(tlist.size).to eq 21
end
it 'generates future events by day' do
t = Time.new(2015,1,31)
s = Schedule.new start_time: t, end_time: t + 40.minutes, repeat: 1, last_time: t + 1.month
tlist = []
while !s.current_start.nil? do
tlist << s.current_start
s.next_time!
end
expect(tlist.size).to eq 29
end
end
describe ScheduleService do
it '日程【2015-07-08 16:00:00,2015-07-08 17:00:00,不重复】与日程【2015-07-06 16:00:00,2015-07-06 16:30:00,每天重复,没有截止日期】冲突' do
s1 = Schedule.new start_time: Time.new(2015, 7, 8, 16), end_time: Time.new(2015, 7, 8, 17)
s2 = Schedule.new start_time: Time.new(2015, 7, 6, 16), end_time: Time.new(2015, 7, 6, 16, 30), repeat: Schedule::R_DAY
expect(ScheduleService.conflicts? s1, s2).to be true
end
it '日程【2015-07-08 16:00:00,2015-07-08 17:00:00,每工作日重复,没有截止日期】与日程【2015-07-11 16:00:00,2015-07-11 17:00:00,每周重复,没有截止日期】 不冲突' do
s1 = Schedule.new start_time: Time.new(2015, 7, 8, 16), end_time: Time.new(2015, 7, 8, 17), repeat: Schedule::R_WDAY
s2 = Schedule.new start_time: Time.new(2015, 7, 11, 16), end_time: Time.new(2015, 7, 11, 17), repeat: Schedule::R_WEEK
expect(ScheduleService.conflicts? s1, s2).to be false
end
it '日程【2015-05-31 16:00:00,2015-05-31 17:00:00,每月重复,截止2015-07-15】与日程【2015-06-10 16:00:00,2015-06-10 17:00:00,每天重复,没有截止日期】不冲突' do
s1 = Schedule.new start_time: Time.new(2015, 5, 31, 16), end_time: Time.new(2015, 5, 31, 17), repeat: Schedule::R_MONTH, last_time: Time.new(2015, 7, 15)
s2 = Schedule.new start_time: Time.new(2015, 6, 10, 16), end_time: Time.new(2015, 6, 10, 17), repeat: Schedule::R_DAY
expect(ScheduleService.conflicts? s1, s2).to be false
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.