forked from rickar/cal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
holiday.go
76 lines (67 loc) · 2.24 KB
/
holiday.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
73
74
75
76
// (c) 2014 Rick Arnold. Licensed under the BSD license (see LICENSE).
package cal
import (
"time"
)
// ObservedRule represents a rule for observing a holiday that falls
// on a weekend.
type ObservedRule int
// Observence
const (
ObservedNearest ObservedRule = iota // nearest weekday (Friday or Monday)
ObservedExact // the exact day only
ObservedMonday // Monday always
)
// United States holidays
var (
USNewYear = NewHoliday(time.January, 1)
USMLK = NewHolidayFloat(time.January, time.Monday, 3)
USPresidents = NewHolidayFloat(time.February, time.Monday, 3)
USMemorial = NewHolidayFloat(time.May, time.Monday, -1)
USIndependence = NewHoliday(time.July, 4)
USLabor = NewHolidayFloat(time.September, time.Monday, 1)
USColumbus = NewHolidayFloat(time.October, time.Monday, 2)
USVeterans = NewHoliday(time.November, 11)
USThanksgiving = NewHolidayFloat(time.November, time.Thursday, 4)
USChristmas = NewHoliday(time.December, 25)
)
// Holiday holds information about the yearly occurrence of a holiday.
//
// A valid Holiday consists of:
// - Month and Day (such as March 14 for Pi Day)
// - Month, Weekday, and Offset (such as the second Monday of October for Columbus Day)
// - Offset (such as the 183rd day of the year for the start of the second half)
type Holiday struct {
Month time.Month
Weekday time.Weekday
Day int
Offset int
}
// NewHoliday creates a new Holiday instance for an exact day of a month.
func NewHoliday(month time.Month, day int) Holiday {
return Holiday{Month: month, Day: day}
}
// NewHolidayFloat creates a new Holiday instance for an offset-based day of
// a month.
func NewHolidayFloat(month time.Month, weekday time.Weekday, offset int) Holiday {
return Holiday{Month: month, Weekday: weekday, Offset: offset}
}
// Matches determines whether the given date is the one referred to by the
// Holiday.
func (h *Holiday) Matches(date time.Time) bool {
if h.Month > 0 {
if date.Month() != h.Month {
return false
}
if h.Day > 0 {
return date.Day() == h.Day
}
if h.Weekday > 0 && h.Offset != 0 {
r := IsWeekdayN(date, h.Weekday, h.Offset)
return r
}
} else if h.Offset > 0 {
return date.YearDay() == h.Offset
}
return false
}