-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcalendar.go
72 lines (62 loc) · 1.51 KB
/
calendar.go
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
package calendar
import (
"sort"
"sync"
"time"
)
type Event struct {
Id string
Start time.Time
End time.Time
}
// byStartTime implements sort.Interface for []Event based on
// the Start field.
type byStartTime []Event
func (s byStartTime) Len() int { return len(s) }
func (s byStartTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s byStartTime) Less(i, j int) bool { return s[i].Start.Before(s[j].Start) }
type Calendar struct {
events map[string]Event
id string
mu sync.Mutex
}
// New returns a new Calendar
func New(id string) *Calendar {
cal := &Calendar{
events: make(map[string]Event),
id: id,
}
return cal
}
// AddEvent adds an event to the calendar
func (c Calendar) AddEvent(e Event) {
c.mu.Lock()
defer c.mu.Unlock()
c.events[e.Id] = e
}
// Events returns all events, ordered by start time
func (c Calendar) Events() []Event {
evs := make([]Event, len(c.events))
i := 0
for _, ev := range c.events {
evs[i] = ev
i = i + 1
}
sort.Sort(byStartTime(evs))
return evs
}
// Available checks calendars for events during range, and returns false
// if any of them have conflicting events
func AvailableRange(start, end time.Time, cals ...*Calendar) bool {
for _, c := range cals {
for _, e := range c.events {
if rangeConflict(e.Start, e.End, start, end) {
return false
}
}
}
return true
}
func rangeConflict(aStart, aEnd, bStart, bEnd time.Time) bool {
return (bStart.After(aStart) && bStart.Before(aEnd)) || (bEnd.After(aStart) && bEnd.Before(aEnd))
}