stillbox/internal/common/intervals.go
2025-02-18 08:58:12 -05:00

84 lines
2.1 KiB
Go

package common
import (
"time"
)
const (
DaysInWeek = 7
MonthsInQuarter = 3
)
type TimeBounder interface {
GetDailyBounds(date time.Time) (lowerBound, upperBound time.Time)
GetWeeklyBounds(date time.Time) (lowerBound, upperBound time.Time)
GetMonthlyBounds(date time.Time) (lowerBound, upperBound time.Time)
GetQuarterlyBounds(date time.Time) (lowerBound, upperBound time.Time)
GetYearlyBounds(date time.Time) (lowerBound, upperBound time.Time)
}
type tbOpt func(*timeBounder)
func WithLocation(l *time.Location) tbOpt {
return func(tb *timeBounder) {
tb.loc = l
}
}
func NewTimeBounder(opts ...tbOpt) timeBounder {
tb := timeBounder{}
for _, opt := range opts {
opt(&tb)
}
if tb.loc == nil {
tb.loc = time.UTC
}
return tb
}
type timeBounder struct {
loc *time.Location
}
func (tb timeBounder) GetDailyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, tb.loc)
upperBound = lowerBound.AddDate(0, 0, 1)
return
}
func (tb timeBounder) GetWeeklyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, tb.loc).AddDate(0, 0, -int(date.Weekday()-time.Monday))
upperBound = lowerBound.AddDate(0, 0, DaysInWeek)
return
}
func (tb timeBounder) GetMonthlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, tb.loc)
upperBound = lowerBound.AddDate(0, 1, 0)
return
}
func (tb *timeBounder) GetQuarterlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
year, _, _ := date.Date()
quarter := (int(date.Month()) - 1) / MonthsInQuarter
firstMonthOfTheQuarter := time.Month(quarter*MonthsInQuarter + 1)
lowerBound = time.Date(year, firstMonthOfTheQuarter, 1, 0, 0, 0, 0, tb.loc)
upperBound = lowerBound.AddDate(0, MonthsInQuarter, 0)
return
}
func (tb timeBounder) GetYearlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), 1, 1, 0, 0, 0, 0, tb.loc)
upperBound = lowerBound.AddDate(1, 0, 0)
return
}