package xtime import ( "fmt" "time" "github.com/golang-module/carbon/v2" ) // 基于Carbon而不是Time // 默认将 SaoPauloTimezoneOffset 作为时区偏移 // 默认将 WeekStartsAt 作为每周起始 // 注意新加的函数都要基于Now() // 设置时区 // reverse:给Now()设置时传false,解析系统时区输出的字符串/时间戳时传true func setLocation(c *carbon.Carbon, offsets ...int) *carbon.Carbon { var loc *time.Location if len(offsets) > 0 { loc = time.FixedZone("CUS", offsets[len(offsets)-1]) } else { loc = time.FixedZone("CST", sysTimezoneOffset) } return c.SetLocation(loc) } func set(c *carbon.Carbon, offsets ...int) *carbon.Carbon { // 设置周起始 c = c.SetWeekStartsAt(WeekStartsAt) // 设置时区 c = setLocation(c, offsets...) return c } func Now(offsets ...int) (c *carbon.Carbon) { c = carbon.Now().AddSeconds(nowOffset) c = set(c, offsets...) return } func ConvertToCarbon[T time.Time | *carbon.Carbon | int64](t T, offsets ...int) *carbon.Carbon { var c *carbon.Carbon switch v := any(t).(type) { case time.Time: c = set(carbon.CreateFromStdTime(v), offsets...) case *carbon.Carbon: c = set(v, offsets...) case int64: c = set(carbon.CreateFromTimestamp(v), offsets...) } return c } // IsTodayTimestamp 判断该时间戳是否为今天 func IsTodayTimestamp[T int | int64](timestamp T, offsets ...int) bool { return IsToday(int64(timestamp), offsets...) } // IsToday 判断时间是否为今天 func IsToday[T time.Time | *carbon.Carbon | int64](t T, offsets ...int) bool { c := ConvertToCarbon(t, offsets...) return c.ToDateString() == Now().ToDateString() } // IsBeforeNow 判断时间t是否在现在之前 // example: // // now := time.Now() // before := time.Now().Add(-time.Hour) // IsBeforeNow(after) // true func IsBeforeNow[T time.Time | *carbon.Carbon | int64](t T, offsets ...int) bool { return !IsAfterNow(t, offsets...) } // IsAfterNow 判断时间t是否在现在之后 // example: // // now := time.Now() // after := time.Now().Add(time.Hour) // IsAfterNow(after) // true func IsAfterNow[T time.Time | *carbon.Carbon | int64](t T, offsets ...int) bool { switch v := any(t).(type) { case time.Time: return IsAfter(v, time.Now(), offsets...) case *carbon.Carbon: return IsAfter(v, Now(), offsets...) case int64: return IsAfter(v, Now().Timestamp()) default: return false } } // IsBefore 判断时间t1是否在t2之前 // example: // t1 := time.Now().Add(-time.Hour) // t2 := time.Now() // IsBefore(t1,t2) // true func IsBefore[T time.Time | *carbon.Carbon | int64](t1, t2 T, offsets ...int) bool { return !IsAfter(t1, t2, offsets...) } // IsAfter 判断时间t1是否在t2之后 // example: // t1 := time.Now().Add(time.Hour) // t2 := time.Now() // IsAfter(t1,t2) // true func IsAfter[T time.Time | *carbon.Carbon | int64](t1, t2 T, offsets ...int) bool { c1, c2 := ConvertToCarbon(t1, offsets...), ConvertToCarbon(t2, offsets...) return c1.Gt(c2) } // TimestampToTime 将时间戳转为 carbon.Carbon 类型 func TimestampToTime[T int | int64](timestamp T, offsets ...int) *carbon.Carbon { return set(carbon.CreateFromTimestamp(int64(timestamp)), offsets...) } // IsInDuration 判断某个时间在某个时间段内 func IsInDuration[T time.Time | *carbon.Carbon | int64](t, start, end T, offsets ...int) bool { return IsAfter(t, start, offsets...) && IsBefore(t, end, offsets...) } // FormatDuration 将起止时间,格式化为 format - format func FormatDuration[T time.Time | *carbon.Carbon | int64](start, end T, layout string, offsets ...int) string { startC, endC := ConvertToCarbon(start, offsets...), ConvertToCarbon(end, offsets...) return fmt.Sprintf("%s - %s", startC.StdTime().Format(layout), endC.StdTime().Format(layout)) } func Yesterday(offsets ...int) *carbon.Carbon { return Now(offsets...).SubDay().StartOfDay() } func Today(offsets ...int) *carbon.Carbon { return Now(offsets...).StartOfDay() } func Tomorrow(offsets ...int) *carbon.Carbon { return Now(offsets...).AddDay().StartOfDay() } func NextNDay(n int, offsets ...int) *carbon.Carbon { return Now(offsets...).AddDays(n).StartOfDay() } func LastWeek(offsets ...int) *carbon.Carbon { return Now(offsets...).SubWeek().StartOfWeek() } func ThisWeek(offsets ...int) *carbon.Carbon { return Now(offsets...).StartOfWeek() } func NextWeek(offsets ...int) *carbon.Carbon { return Now(offsets...).AddWeek().StartOfWeek() } func NextNWeek(n int, offsets ...int) *carbon.Carbon { return Now(offsets...).AddWeeks(n).StartOfWeek() } func LastMonth(offsets ...int) *carbon.Carbon { return Now(offsets...).SubMonth().StartOfMonth() } func ThisMonth(offsets ...int) *carbon.Carbon { return Now(offsets...).StartOfMonth() } func NextMonth(offsets ...int) *carbon.Carbon { return Now(offsets...).AddMonth().StartOfMonth() } func NextNMonth(n int, offsets ...int) *carbon.Carbon { return Now(offsets...).AddMonths(n).StartOfMonth() } func LastQuarter(offsets ...int) *carbon.Carbon { return Now(offsets...).SubQuarter().StartOfQuarter() } func ThisQuarter(offsets ...int) *carbon.Carbon { return Now(offsets...).StartOfQuarter() } func NextQuarter(offsets ...int) *carbon.Carbon { return Now(offsets...).AddQuarter().StartOfQuarter() } func NextNQuarter(n int, offsets ...int) *carbon.Carbon { return Now(offsets...).AddQuarters(n).StartOfQuarter() } func LastYear(offsets ...int) *carbon.Carbon { return Now(offsets...).SubYear().StartOfYear() } func ThisYear(offsets ...int) *carbon.Carbon { return Now(offsets...).StartOfYear() } func NextYear(offsets ...int) *carbon.Carbon { return Now(offsets...).AddYear().StartOfYear() } func NextNYear(n int, offsets ...int) *carbon.Carbon { return Now(offsets...).AddYears(n).StartOfYear() }