-
Notifications
You must be signed in to change notification settings - Fork 90
/
calendar.rb
executable file
·85 lines (73 loc) · 2.49 KB
/
calendar.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
module RedmineBetterGanttChart
module Calendar
def self.workdays_between(date_from, date_to)
date_from, date_to = date_to, date_from if date_to < date_from
number_of_days_in(date_from, date_to) { |d| is_a_working_day?(d) }
end
def self.weekends_between(date_from, date_to)
date_from, date_to = date_to, date_from if date_to < date_from
number_of_days_in(date_from, date_to) { |d| !is_a_working_day?(d) }
end
def self.next_working_day(date)
the_same_day_or(date) { next_day_of_week(1, date) }
end
def self.previous_working_day(date)
the_same_day_or(date) { previous_day_of_week(5, date) }
end
def self.workdays_from_date(date, shift)
end_date = date + shift.days
if RedmineBetterGanttChart.work_on_weekends?
end_date
else
start_date = date
if shift > 0
while true
break if (range = weekends_between(start_date, end_date).days) == 0
start_date = end_date
start_date += 1.days if start_date.wday == 6 || start_date.wday == 0
end_date = end_date + range
end
next_working_day(end_date)
else
while true
break if (weekend_diff = weekends_between(start_date, end_date)) == 0
start_date = end_date
start_date -= 1.days if start_date.wday == 6 || start_date.wday == 0
end_date = end_date - weekend_diff.days
end
previous_working_day(end_date)
end
end
end
def self.workdays_before_date(date, shift)
workdays_from_date(date, -shift)
end
# Returns nearest requested day of week, for example
# next_day_of_week(5) will return next Friday
# next_day_of_week(5, Date.today + 7) will return Friday of the next week
def self.next_day_of_week(wday, from = Date.today)
from + (wday + 7 - from.wday) % 7
end
def self.previous_day_of_week(wday, from = Date.today)
from - (from.wday - wday + 7) % 7
end
def self.working_days
RedmineBetterGanttChart.work_on_weekends? ? 0..6 : 1..5
end
def self.is_a_working_day?(date)
working_days.include?(date.wday)
end
def self.number_of_days_in(date_from, date_to, &block)
(date_from..date_to).select do |date|
yield date
end.size
end
def self.the_same_day_or(date)
if RedmineBetterGanttChart.work_on_weekends? || is_a_working_day?(date)
date
else
yield
end
end
end
end