package main import "time" type YMD uint32 type YM uint32 // YYYYMM max 6 digits. // YYYYMMDD max 8 digits. int32. // // Store dates as uint32 // YYYYMMDD // // So: Jan 21, 2022 => 20220121 // Jan 2022 => 202201 // func (d *YMD) Year() int { return int(*d) / 10000 } func (d *YMD) Month() int { return (int(*d) / 100) % 100 } func (d *YMD) Day() int { return int(*d) % 100 } func (d *YMD) YM() YM { return YM(int(*d) / 100) } // Set day - does no validation func (d *YMD) SetDay(day int) { var i int = int(*d) i -= (i % 100) i += day *d = YMD(i) } // Make the first of the month func (d *YMD) First() { d.SetDay(1) } // Make end of month func (d *YMD) Last() { var value int = int(*d) // time.Date will normalize the date for us. // set Month +1, and day to 0 (gives us last day of previous month) var lastDay time.Time = time.Date(value/10000, time.Month((value/100)%100)+1, 0, 4, 3, 2, 1, time.Local) *d = YMD(lastDay.Year()*10000 + int(lastDay.Month())*100 + lastDay.Day()) } func NewYMD(year, month, day int) YMD { return YMD(year*10000 + month*100 + day) } func (d *YMD) YMD() (int, int, int) { var i int = int(*d) return i / 10000, (i / 100) % 100, i % 100 } func (d *YMD) Time() time.Time { var value int = int(*d) return time.Date(value/10000, time.Month((value/100)%100), value%100, 2, 2, 2, 0, time.Local) } // Convert time.Time to DBDate func NewYMDFromTime(point time.Time) YMD { return YMD(point.Year()*10000 + int(point.Month())*100 + point.Day()) } // Convert DBDate to time.Time func ToTime(point YMD) time.Time { // I'm not sure about hours, minutes, seconds. var value int = int(point) var result time.Time = time.Date(value/10000, time.Month((value/100)%100), value%100, 2, 2, 2, 0, time.Local) return result } func NewYM(year, month int) YM { return YM(year*100 + month) } func (d *YM) Year() int { return int(*d) / 100 } func (d *YM) Month() int { return int(*d) % 100 } func (d *YM) YMD() YMD { return YMD(int(*d)*100 + 1) }