-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
weekday.go
134 lines (114 loc) · 3.97 KB
/
weekday.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package timex
import "time"
// RangeDate returns a function which returns a time
// between "start" and "end". When the iteration finishes
// the returned time is zero.
func RangeDate(start, end time.Time) func() time.Time {
y, m, d := start.Date()
start = time.Date(y, m, d, 0, 0, 0, 0, start.Location())
y, m, d = end.Date()
end = time.Date(y, m, d, 0, 0, 0, 0, end.Location())
return func() time.Time {
if start.After(end) {
return time.Time{}
}
date := start
start = start.AddDate(0, 0, 1)
return date
}
}
type DateRangeType string
const (
DayRange DateRangeType = "day"
MonthRange DateRangeType = "month"
WeekRange DateRangeType = "week"
YearRange DateRangeType = "year"
)
// Between returns the dates from "start" to "end".
func Between(start, end time.Time) []time.Time {
var dates []time.Time
for df := RangeDate(start, end); ; {
d := df()
if d.IsZero() {
break
}
dates = append(dates, d)
}
return dates
}
// Backwards returns a list of dates between "end" and -n (years, months, weeks or days).
func Backwards(typ DateRangeType, end time.Time, n int) []time.Time {
var start time.Time
switch typ {
case DayRange:
n = n - 1 // -7 should be -6 to get the week from today.
start = end.AddDate(0, 0, -n)
case WeekRange:
// 7 should be 6 to get the week.
start = end.AddDate(0, 0, -n*6)
case MonthRange:
start = end.AddDate(0, -n, 0)
case YearRange:
start = end.AddDate(-n, 0, 0)
}
return Between(start, end)
}
// BackwardsN returns the dates from back to "n" years, months, weeks or days from today.
func BackwardsN(typ DateRangeType, n int) []time.Time {
end := time.Now()
return Backwards(typ, end, n)
}
// BackwardsToMonday returns the dates between "end" (including "end")
// until the previous monday of the current week (including monday).
func BackwardsToMonday(end time.Time) []time.Time {
dates := []time.Time{end}
for end.Weekday() != time.Monday {
end = end.AddDate(0, 0, -1)
dates = append(dates, end)
}
return dates
}
// GetWeekDate returns the date of the given weekday (monday, tuesday, etc.) of the current week.
func GetWeekDate(now time.Time, weekday, start, end time.Weekday) time.Time {
dates := GetWeekdays(now, start, end)
for _, d := range dates {
if d.Weekday() == weekday {
return d
}
}
return time.Time{}
}
// GetWeekStart returns the date of the first week day (startWeekday) of the current now's week.
func GetWeekStart(now time.Time, startWeekday time.Weekday) time.Time {
offset := (int(startWeekday) - int(now.Weekday()) - 7) % 7
date := now.Add(time.Duration(offset*24) * time.Hour)
return date
}
// GetWeekEnd returns the date of the last week day (endWeekday) of the current now's week.
func GetWeekEnd(now time.Time, endWeekday time.Weekday) time.Time {
offset := (int(endWeekday) - int(now.Weekday()) + 7) % 7
date := now.Add(time.Duration(offset*24) * time.Hour)
return date
}
// GetWeekdays returns the range between "startWeekday" and "endWeekday" of the current week.
func GetWeekdays(now time.Time, startWeekday, endWeekday time.Weekday) (dates []time.Time) {
return Between(GetWeekStart(now, startWeekday), GetWeekEnd(now, endWeekday))
}
// GetMonthStart returns the date of the first month day of the current now's month.
func GetMonthStart(now time.Time) time.Time {
return time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
}
// GetMonthEnd returns the date of the last month day of the current now's month.
func GetMonthEnd(now time.Time) time.Time {
now = now.UTC()
// Add one month to the current date and subtract one day
return time.Date(now.Year(), now.Month()+1, 0, 0, 0, 0, 0, now.Location())
}
// GetMonthDays returns the range between first and last days the current month.
func GetMonthDays(now time.Time) (dates []time.Time) {
return Between(GetMonthStart(now), GetMonthEnd(now))
}
// GetYearStart returns the date of the first year of the current now's year.
func GetYearStart(now time.Time) time.Time {
return time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
}