187 lines
5.8 KiB
Go
187 lines
5.8 KiB
Go
package tools
|
||
|
||
import (
|
||
"time"
|
||
)
|
||
|
||
// TimeInfo 详细时间信息结构
|
||
type TimeInfo struct {
|
||
UTC string `json:"utc"` // UTC时间
|
||
Local string `json:"local"` // 用户时区时间
|
||
Unix int64 `json:"unix"` // Unix时间戳
|
||
Timezone string `json:"timezone"` // 时区名称
|
||
Offset int `json:"offset"` // 时区偏移量(小时)
|
||
RFC3339 string `json:"rfc3339"` // RFC3339格式
|
||
DateTime string `json:"datetime"` // 日期时间格式
|
||
Date string `json:"date"` // 日期格式
|
||
Time string `json:"time"` // 时间格式
|
||
}
|
||
|
||
// GetTimestamp 获取当前时间戳(秒)
|
||
func GetTimestamp() int64 {
|
||
return time.Now().Unix()
|
||
}
|
||
|
||
// GetMillisTimestamp 获取当前时间戳(毫秒)
|
||
func GetMillisTimestamp() int64 {
|
||
return time.Now().UnixMilli()
|
||
}
|
||
|
||
// FormatTimeWithLayout 格式化时间(自定义格式)
|
||
func FormatTimeWithLayout(t time.Time, layout string) string {
|
||
if layout == "" {
|
||
layout = "2006-01-02 15:04:05"
|
||
}
|
||
return t.Format(layout)
|
||
}
|
||
|
||
// ParseTime 解析时间字符串
|
||
func ParseTime(timeStr, layout string) (time.Time, error) {
|
||
if layout == "" {
|
||
layout = "2006-01-02 15:04:05"
|
||
}
|
||
return time.Parse(layout, timeStr)
|
||
}
|
||
|
||
// GetCurrentTime 获取当前时间字符串
|
||
func GetCurrentTime() string {
|
||
return FormatTimeWithLayout(time.Now(), "")
|
||
}
|
||
|
||
// 注意:GetBeginOfDay、GetEndOfDay 已在 datetime.go 中实现为 StartOfDay、EndOfDay
|
||
// datetime.go 中的方法支持时区参数,功能更强大,建议使用 datetime.go 中的方法
|
||
|
||
// GetBeginOfWeek 获取某周的开始时间(周一)
|
||
func GetBeginOfWeek(t time.Time) time.Time {
|
||
weekday := t.Weekday()
|
||
if weekday == time.Sunday {
|
||
weekday = 7
|
||
}
|
||
// 使用 datetime.go 中的 StartOfDay 方法(需要时区,这里使用时间对象本身的时区)
|
||
beginDay := t.AddDate(0, 0, int(1-weekday))
|
||
return time.Date(beginDay.Year(), beginDay.Month(), beginDay.Day(), 0, 0, 0, 0, beginDay.Location())
|
||
}
|
||
|
||
// GetEndOfWeek 获取某周的结束时间(周日)
|
||
func GetEndOfWeek(t time.Time) time.Time {
|
||
beginOfWeek := GetBeginOfWeek(t)
|
||
endDay := beginOfWeek.AddDate(0, 0, 6)
|
||
return time.Date(endDay.Year(), endDay.Month(), endDay.Day(), 23, 59, 59, 999999999, endDay.Location())
|
||
}
|
||
|
||
// 注意:GetBeginOfMonth、GetEndOfMonth、GetBeginOfYear、GetEndOfYear 已在 datetime.go 中实现
|
||
// datetime.go 中的方法(StartOfMonth、EndOfMonth、StartOfYear、EndOfYear)支持时区参数,功能更强大
|
||
// 建议使用 datetime.go 中的方法
|
||
|
||
// AddHours 增加小时数
|
||
func AddHours(t time.Time, hours int) time.Time {
|
||
return t.Add(time.Duration(hours) * time.Hour)
|
||
}
|
||
|
||
// AddMinutes 增加分钟数
|
||
func AddMinutes(t time.Time, minutes int) time.Time {
|
||
return t.Add(time.Duration(minutes) * time.Minute)
|
||
}
|
||
|
||
// 注意:DiffDays、DiffHours、DiffMinutes、DiffSeconds 方法已在 datetime.go 中实现
|
||
// 请使用 datetime.go 中的方法,它们支持更精确的计算和统一的返回类型
|
||
|
||
// IsToday 判断是否为今天
|
||
func IsToday(t time.Time) bool {
|
||
now := time.Now()
|
||
tBegin := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||
nowBegin := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||
return tBegin.Equal(nowBegin)
|
||
}
|
||
|
||
// GenerateTimeInfoWithTimezone 生成详细时间信息(指定时区)
|
||
func GenerateTimeInfoWithTimezone(t time.Time, timezone string) TimeInfo {
|
||
// 加载时区
|
||
loc, err := time.LoadLocation(timezone)
|
||
if err != nil {
|
||
loc = time.UTC
|
||
timezone = "UTC"
|
||
}
|
||
|
||
// 转换为指定时区时间
|
||
localTime := t.In(loc)
|
||
|
||
// 计算时区偏移量
|
||
_, offset := localTime.Zone()
|
||
offsetHours := offset / 3600
|
||
|
||
// 预先计算格式化结果,避免重复调用
|
||
utcRFC3339 := t.UTC().Format(time.RFC3339)
|
||
localRFC3339 := localTime.Format(time.RFC3339)
|
||
localDateTime := localTime.Format("2006-01-02 15:04:05")
|
||
localDate := localTime.Format("2006-01-02")
|
||
localTimeOnly := localTime.Format("15:04:05")
|
||
|
||
return TimeInfo{
|
||
UTC: utcRFC3339,
|
||
Local: localRFC3339,
|
||
Unix: t.Unix(),
|
||
Timezone: timezone,
|
||
Offset: offsetHours,
|
||
RFC3339: localRFC3339,
|
||
DateTime: localDateTime,
|
||
Date: localDate,
|
||
Time: localTimeOnly,
|
||
}
|
||
}
|
||
|
||
// GetUTCTimestamp 获取UTC时间戳
|
||
func GetUTCTimestamp() int64 {
|
||
return time.Now().UTC().Unix()
|
||
}
|
||
|
||
// GetUTCTimestampFromTime 从指定时间获取UTC时间戳
|
||
func GetUTCTimestampFromTime(t time.Time) int64 {
|
||
return t.UTC().Unix()
|
||
}
|
||
|
||
// FormatTimeUTC 格式化时间为UTC字符串(ISO 8601格式)
|
||
func FormatTimeUTC(t time.Time) string {
|
||
return t.UTC().Format(time.RFC3339)
|
||
}
|
||
|
||
// IsYesterday 判断是否为昨天
|
||
func IsYesterday(t time.Time) bool {
|
||
yesterday := time.Now().AddDate(0, 0, -1)
|
||
tBegin := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||
yesterdayBegin := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, yesterday.Location())
|
||
return tBegin.Equal(yesterdayBegin)
|
||
}
|
||
|
||
// IsTomorrow 判断是否为明天
|
||
func IsTomorrow(t time.Time) bool {
|
||
tomorrow := time.Now().AddDate(0, 0, 1)
|
||
tBegin := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||
tomorrowBegin := time.Date(tomorrow.Year(), tomorrow.Month(), tomorrow.Day(), 0, 0, 0, 0, tomorrow.Location())
|
||
return tBegin.Equal(tomorrowBegin)
|
||
}
|
||
|
||
// GenerateTimeInfoFromContext 从gin.Context中获取用户时区并生成时间信息
|
||
func GenerateTimeInfoFromContext(t time.Time, c interface{}) TimeInfo {
|
||
// 尝试从context中获取时区
|
||
timezone := ""
|
||
|
||
// 如果传入的是gin.Context,尝试获取时区
|
||
if ginCtx, ok := c.(interface {
|
||
Get(key string) (value interface{}, exists bool)
|
||
}); ok {
|
||
if tz, exists := ginCtx.Get("user_timezone"); exists {
|
||
if tzStr, ok := tz.(string); ok && tzStr != "" {
|
||
timezone = tzStr
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果没有获取到时区,使用默认时区(东8区)
|
||
if timezone == "" {
|
||
timezone = "Asia/Shanghai"
|
||
}
|
||
|
||
return GenerateTimeInfoWithTimezone(t, timezone)
|
||
}
|