// model/period.go package model import ( "fmt" "time" ) func QuarterPeriod(year, q int) Period { months := map[int][2]int{ 1: {1, 3}, 2: {4, 6}, 3: {7, 9}, 4: {10, 12}, } m := months[q] return Period{ Type: PeriodQuarter, Year: year, Index: q, Start: date(year, m[0], 1), End: date(year, m[1]+1, 0), // last day of end month } } func HalfYearPeriod(year, h int) Period { if h == 1 { return Period{Type: PeriodHalfYear, Year: year, Index: 1, Start: date(year, 1, 1), End: date(year, 7, 0)} } return Period{Type: PeriodHalfYear, Year: year, Index: 2, Start: date(year, 7, 1), End: date(year, 12, 31)} } func FullYearPeriod(year int) Period { return Period{Type: PeriodYear, Year: year, Index: 1, Start: date(year, 1, 1), End: date(year, 12, 31)} } func (p Period) String() string { switch p.Type { case PeriodQuarter: return fmt.Sprintf("Q%d %d", p.Index, p.Year) case PeriodHalfYear: return fmt.Sprintf("H%d %d", p.Index, p.Year) case PeriodYear: return fmt.Sprintf("FY%d", p.Year) } return "unknown" } func date(year, month, day int) time.Time { // day=0 means last day of previous month return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) }