Skip to content

Commit

Permalink
feat: time/timeutil: add Yearquarter, `TimeMore.QuarterCalendar()…
Browse files Browse the repository at this point in the history
…`, `TimeMore.SeasonMeteorological()`
  • Loading branch information
grokify committed Dec 9, 2023
1 parent d3e4c30 commit 75aa86a
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 16 deletions.
22 changes: 22 additions & 0 deletions time/timeutil/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,25 @@ const (

MonthsEN = `["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]`
)

// A Yearquarter specifies a quarter of the year (Winter = 1, ...).
type Yearquarter uint8

const (
Winter Yearquarter = 1 + iota
Spring
Summer
Autumn
)

/*
// String returns the English name of the quarter ("Winter", "Spring", ...).
func (Yearquarter) String() string {
if January <= m && m <= December {
return longMonthNames[m-1]
}
buf := make([]byte, 20)
n := fmtInt(buf, uint64(m))
return "%!Month(" + string(buf[n:]) + ")"
}
*/
6 changes: 3 additions & 3 deletions time/timeutil/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,17 @@ func GetFormat(formatName string) (string, error) {

// FormatQuarter takes quarter time and formats it using "Q# YYYY".
func FormatQuarter(t time.Time) string {
return fmt.Sprintf("Q%d %d", MonthToQuarter(uint8(t.Month())), t.Year())
return fmt.Sprintf("Q%d %d", MonthToQuarter(t.Month()), t.Year())
}

// FormatQuarter takes quarter time and formats it using "YYYY Q#".
func FormatQuarterYYYYQ(t time.Time) string {
return fmt.Sprintf("%d Q%d", t.Year(), MonthToQuarter(uint8(t.Month())))
return fmt.Sprintf("%d Q%d", t.Year(), MonthToQuarter(t.Month()))
}

// FormatQuarterYYQ takes quarter time and formats it using "'YY Q#".
func FormatQuarterYYQ(t time.Time) string {
return fmt.Sprintf("%s Q%d", t.Format("'06"), MonthToQuarter(uint8(t.Month())))
return fmt.Sprintf("%s Q%d", t.Format("'06"), MonthToQuarter(t.Month()))
}

func TimeMinRFC3339() time.Time {
Expand Down
14 changes: 9 additions & 5 deletions time/timeutil/quarter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func QuarterStart(dt time.Time) time.Time {

func QuarterStartString(t time.Time) string {
dtStart := NewTimeMore(t, 0).QuarterStart()
return fmt.Sprintf("%v Q%v", dtStart.Year(), MonthToQuarter(uint8(dtStart.Month())))
return fmt.Sprintf("%v Q%v", dtStart.Year(), MonthToQuarter(dtStart.Month()))
}

/*
Expand Down Expand Up @@ -66,11 +66,15 @@ func quarterPrev(t time.Time, num uint) time.Time {
}

// MonthToQuarter converts a month to a calendar quarter.
func MonthToQuarter(month uint8) uint8 {
return uint8(math.Ceil(float64(month) / 3))
func MonthToQuarter(month time.Month) Yearquarter {
// func MonthToQuarter(month uint8) uint8 {
// return uint8(math.Ceil(float64(month) / 3))
return Yearquarter(uint8(math.Ceil(float64(month) / 3)))
}

// QuarterToMonth converts a calendar quarter to a month.
func QuarterToMonth(quarter uint8) uint8 {
return quarter*3 - 2
func QuarterToMonth(quarter Yearquarter) time.Month {
// func QuarterToMonth(quarter uint8) uint8 {
// return quarter*3 - 2
return time.Month(int(quarter)*3 - 2)
}
6 changes: 3 additions & 3 deletions time/timeutil/quarter_int.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func EqualQuarter(dt1, dt2 time.Time) bool {

func QuarterInt32ForTime(dt time.Time) int32 {
dt = dt.UTC()
q := MonthToQuarter(uint8(dt.Month()))
q := MonthToQuarter(dt.Month())
return (int32(dt.Year()) * int32(10)) + int32(q)
}

Expand Down Expand Up @@ -135,7 +135,7 @@ func QuarterInt32StartTime(yyyyq int32) (time.Time, error) {
if err != nil {
return time.Now(), err
}
qm := QuarterToMonth(q)
qm := QuarterToMonth(Yearquarter(q))
return time.Date(int(yyyy), time.Month(qm), 1, 0, 0, 0, 0, time.UTC), nil

Check failure on line 139 in time/timeutil/quarter_int.go

View workflow job for this annotation

GitHub Actions / lint (1.x, ubuntu-latest)

unnecessary conversion (unconvert)
}

Expand Down Expand Up @@ -165,7 +165,7 @@ func QuarterInt32End(yyyyq int32) (time.Time, error) {
} else {
q += 1
}
qm := QuarterToMonth(q)
qm := QuarterToMonth(Yearquarter(q))
return time.Date(int(yyyy), time.Month(qm), 0, 23, 59, 59, 0, time.UTC), nil

Check failure on line 169 in time/timeutil/quarter_int.go

View workflow job for this annotation

GitHub Actions / lint (1.x, ubuntu-latest)

unnecessary conversion (unconvert)
}

Expand Down
8 changes: 4 additions & 4 deletions time/timeutil/quarter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ var monthToQuarterTests = []struct {

func TestMonthToQuarter(t *testing.T) {
for _, tt := range monthToQuarterTests {
got := MonthToQuarter(tt.v)
if got != tt.want {
got := MonthToQuarter(time.Month(tt.v))
if got != Yearquarter(tt.want) {
t.Errorf("MonthToQuarter(%v): want %v, got %v", tt.v, tt.want, got)
}
}
Expand All @@ -62,8 +62,8 @@ var quarterToMonthTests = []struct {

func TestQuarterToMonth(t *testing.T) {
for _, tt := range quarterToMonthTests {
got := QuarterToMonth(tt.v)
if got != tt.want {
got := QuarterToMonth(Yearquarter(tt.v))
if got != time.Month(tt.want) {
t.Errorf("QuarterToMonth(%v): want %v, got %v", tt.v, tt.want, got)
}
}
Expand Down
2 changes: 1 addition & 1 deletion time/timeutil/start_end.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func monthStart(dt time.Time) time.Time {

// quarterStart returns a time.Time for the start of the quarter.
func quarterStart(t time.Time) time.Time {
qm := QuarterToMonth(MonthToQuarter(uint8(t.Month())))
qm := QuarterToMonth(MonthToQuarter(t.Month()))
return time.Date(t.Year(), time.Month(qm), 1, 0, 0, 0, 0, t.Location())

Check failure on line 31 in time/timeutil/start_end.go

View workflow job for this annotation

GitHub Actions / lint (1.x, ubuntu-latest)

unnecessary conversion (unconvert)
}

Expand Down
29 changes: 29 additions & 0 deletions time/timeutil/timemore.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,35 @@ func (tm TimeMore) IntervalStart(interval Interval) (time.Time, error) {
return intervalStart(tm.time, interval, tm.weekStartDay)
}

// QuarterCalendar returns the quarter of the year specified by tm.Time.
func (tm TimeMore) QuarterCalendar() Yearquarter {
m := tm.time.Month()
if m < 4 {
return Winter // 1
} else if m < 7 {
return Spring
} else if m < 10 {
return Summer
} else {
return Autumn
}
}

func (tm TimeMore) SeasonMeteorological() Yearquarter {
m := tm.time.Month()
if m < 3 {
return Winter // Starts December 1
} else if m < 6 {
return Spring // Starts March 1
} else if m < 9 {
return Summer // Starts June 1
} else if m < 12 {
return Autumn // Starts September 1
} else {
return Winter // Starts December 1
}
}

// TimeMeta is a struct for holding various times related
// to a current time, including year start, quarter start,
// month start, and week start.
Expand Down

0 comments on commit 75aa86a

Please sign in to comment.