fox/xtime/timex.go
2025-05-26 16:02:54 +08:00

210 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}