iris/x/timex/weekday.go

135 lines
4.0 KiB
Go

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())
}