package common import ( "errors" "time" ) var ( _zero = time.Time{} yearError = errors.New("年份不能为负数") monthError = errors.New("月份不能大于12或小于1") dayError = errors.New("日期不能大于31或小于1") outOfBindTimeError = errors.New("查询时间大于当前系统时间") ) type TimeDay struct { Year int `json:"year"` // 年 Month uint8 `json:"month"` // 月份 Day int `json:"day"` // 日期 } // 根据日期获取每月的开始和结束时间 /** 规则:1、月份大于当前时间抛出异常 2、当前时间属于当前月份,最后时间返回当前时间的次日0点 3、查询月份小于当前月,则返回正常区间 4、格式不符合抛出异常,比如年份=0或者<0,月份是0或负数或者大于12 */ func (day TimeDay) GetMonthWithError() (start time.Time, end time.Time, err error) { if day.Year <= 0 { return _zero, _zero, yearError } if day.Month < 1 || day.Month > 12 { return _zero, _zero, monthError } now := time.Now() // 月份开始时间,大于当前时间,直接异常 dateStart := time.Date(day.Year, time.Month(day.Month), 1, 0, 0, 0, 0, time.Local) if dateStart.After(now) { return _zero, _zero, outOfBindTimeError } // 月份结束时间,如果大于当前时间,取当前时间的 day+1 dateEnd := time.Date(day.Year, time.Month(day.Month+1), 1, 0, 0, 0, 0, time.Local) if dateEnd.After(now) { year, month, day := now.Date() return dateStart, time.Date(year, month, day+1, 0, 0, 0, 0, time.Local), nil } // 正常结束 return dateStart, dateEnd, nil } func (day TimeDay) GetMonthSecWithError() (start int64, end int64, err error) { s, e, err := day.GetMonthWithError() if err != nil { return 0, 0, err } return Time2Second(s), Time2Second(e), nil } // 根据日期获取 每日的开始和结束时间 /** 规则:1、规则不符合抛出异常 2、Mysql的Between属于左闭右闭,所以保证准确性应该是 2020-09-03 00:00:00 和 2020-09-03 23:59:59 这里推荐使用Between函数,因为between函数最终解析成了 2020-09-03 00:00:00 <= x <= 2020-09-03 23:59:59 2020-09-03 返回 2020-09-03 00:00:00 和 2020-09-03 23:59:59 */ func (day TimeDay) GetDayWithError() (start time.Time, end time.Time, err error) { if day.Year <= 0 { return _zero, _zero, yearError } if day.Month < 1 || day.Month > 12 { return _zero, _zero, monthError } if day.Day < 1 || day.Day > 31 { return _zero, _zero, dayError } s := time.Date(day.Year, time.Month(day.Month), day.Day, 0, 0, 0, 0, time.Local) e := GetTomorrow(s).Add(-time.Second) return s, e, nil } func (day TimeDay) GetDaySecWithError() (start int64, end int64, err error) { s, e, err := day.GetDayWithError() if err != nil { return 0, 0, err } return Time2Second(s), Time2Second(e), nil }