Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

184 lines
4.7 KiB
Go

package timeutil
import (
"math"
"math/rand"
"strconv"
"time"
"github.com/jinzhu/now"
)
const (
Day = time.Hour * 24
MinuteSeconds = 60
HourSeconds = 60 * MinuteSeconds
DaySeconds = 24 * HourSeconds
)
// MonthStartEndTime 返回这月1号的0点和下月1号的0点
// 2006-02-02 12:34:56 => 2016-01-01 00:00:00, 2016-02-01 00:00:00
func MonthStartEndTime(t time.Time) (time.Time, time.Time) {
start := now.New(t).BeginningOfMonth()
end := start.AddDate(0, 1, 0)
return start, end
}
// Age 计算年龄
func Age(birthday time.Time, t time.Time) int {
btm := birthday
now_ := t
if btm.After(now_) {
return 0
}
age := now_.Year() - btm.Year()
if now_.Month() < btm.Month() {
age--
} else if now_.Month() == btm.Month() {
if now_.Day() < btm.Day() {
age--
}
}
return age
}
// MidnoonOfDay 一天正午12点
func MidnoonOfDay(t time.Time) time.Time {
return BeginningOfDay(t).Add(12 * time.Hour)
}
func Now() time.Time {
return time.Now().Local()
}
func BeginOfToday() time.Time {
t := Now()
return BeginOfTime(t)
}
func BeginOfTime(t time.Time) time.Time {
year, month, day := t.Date()
return time.Date(year, month, day, 0, 0, 0, 0, t.Location())
}
// BeginningOfDay 一天的开始
func BeginningOfDay(t time.Time) time.Time {
return now.New(t).BeginningOfDay()
}
// BeginningOfTomorrow 明天的开始
func BeginningOfTomorrow(t time.Time) time.Time {
return BeginningOfDay(t).AddDate(0, 0, 1)
}
// BeginningOfMonth 月的开始
func BeginningOfMonth(t time.Time) time.Time {
return now.New(t).BeginningOfMonth()
}
// BeginningOfWeek 周的开始 当前时间的周一零点
func BeginningOfWeek(t time.Time) time.Time {
return now.New(t.Add(-time.Hour * 24)).BeginningOfWeek().Add(+time.Hour * 24)
}
// TailOfWeek 周的结束 当前时间的周一零点
func TailOfWeek(t time.Time) time.Time {
return now.New(t.Add(-time.Hour * 24)).BeginningOfWeek()
}
// StrTimeToTime 时间字符串转时间
func StrTimeToTime(strTime string) (t time.Time) {
timeLayout := "2006-01-02T15:04:05-07:00"
loc, _ := time.LoadLocation("Local")
t, _ = time.ParseInLocation(timeLayout, strTime, loc)
return
}
// 多少分之前
func BeforeMinute(min int) time.Time {
negativeM, _ := time.ParseDuration("-" + strconv.Itoa(min) + "m")
return time.Now().Add(negativeM)
}
// 近几个月 返回时间的上两个月的月初 只支持向前12月
func NearMonth(t time.Time, m time.Month) time.Time {
tM := t.Month() - m
if tM < 0 {
tM = 12 + tM
return time.Date(t.Year()-1, tM, 1, 0, 0, 0, 0, time.Local)
}
return time.Date(t.Year(), tM, 1, 0, 0, 0, 0, time.Local)
}
// MillisecondConsistency 毫秒为000时毫秒+1保证毫米精度不丢失
func MillisecondConsistency(s time.Time) time.Time {
timestamp := s.UnixNano() / 1e6
if timestamp%1000 == 0 {
return time.Unix(0, (timestamp+1)*1e6)
}
return s
}
// MonthStartEndTime 返回这月1号的0点和下月1号的0点
// 2006-02-02 12:34:56 => 2016-01-01 00:00:00, 2016-02-01 00:00:00
func EarlyLastMonth(t time.Time) (time.Time, time.Time) {
start := now.New(t).BeginningOfMonth()
end := start.AddDate(0, 1, 0)
return start, end
}
// MonthStartEndTime 返回当天的0点和后一天的0点
// 2006-02-02 12:34:56 => 2016-02-02 00:00:00, 2016-02-03 00:00:00
func EarlyLastDay(t time.Time) (time.Time, time.Time) {
start := now.New(t).BeginningOfDay()
end := start.AddDate(0, 0, 1)
return start, end
}
// MonthStartEndTime 返回前一天的0点和今天的0点
// 2006-02-02 12:34:56 => 2016-02-02 00:00:00, 2016-02-03 00:00:00
func YesterdayDay(t time.Time) (time.Time, time.Time) {
tmp := t.AddDate(0, 0, -1)
start := BeginningOfDay(tmp)
end := start.AddDate(0, 0, 1)
return start, end
}
// 按指定的基础时间,指定的范围随机一个时间 向前随机一个时间
func RandAddTime(baseTime time.Time, max time.Duration) time.Time {
sum := int64(rand.Intn(int(math.Ceil(max.Seconds()))))
return time.Unix(baseTime.Unix()+sum, 0)
}
// 按指定的基础时间,指定的范围随机一个时间 向后随机一个时间
func RandReduceTime(baseTime time.Time, max time.Duration) time.Time {
sum := int64(rand.Intn(int(math.Ceil(max.Seconds()))))
return time.Unix(baseTime.Unix()-sum, 0)
}
// 根据月份和年返回当月0点和下月0点
func GetTimeByMonthAndYear(m int, y int) (time.Time, time.Time) {
t := time.Date(y, time.Month(m), 1, 0, 0, 0, 0, time.Local)
nextM := t.AddDate(0, 1, 0)
return t, nextM
}
// 增加时间, 年、月、日
func AddTimeByCombo(tm *time.Time, typ string, duration int) *time.Time {
if tm == nil {
return tm
}
date := time.Time{}
switch typ {
case "day":
date = tm.AddDate(0, 0, duration)
case "month":
date = tm.AddDate(0, duration, 0)
case "year":
date = tm.AddDate(duration, 0, 0)
}
return &date
}