调整项目结构,factory只负责暴露方法,不实现业务细节

This commit is contained in:
2025-12-07 00:04:01 +08:00
parent b66f345281
commit 339920a940
23 changed files with 2165 additions and 1231 deletions

358
tools/datetime.go Normal file
View File

@@ -0,0 +1,358 @@
package tools
import (
"fmt"
"time"
)
// TimeZone 时区常量
const (
UTC = "UTC"
AsiaShanghai = "Asia/Shanghai"
AmericaNewYork = "America/New_York"
EuropeLondon = "Europe/London"
AsiaTokyo = "Asia/Tokyo"
)
// DefaultTimeZone 默认时区
var DefaultTimeZone = UTC
// SetDefaultTimeZone 设置默认时区
func SetDefaultTimeZone(timezone string) error {
_, err := time.LoadLocation(timezone)
if err != nil {
return fmt.Errorf("invalid timezone: %w", err)
}
DefaultTimeZone = timezone
return nil
}
// GetLocation 获取时区Location对象
func GetLocation(timezone string) (*time.Location, error) {
if timezone == "" {
timezone = DefaultTimeZone
}
return time.LoadLocation(timezone)
}
// Now 获取当前时间(使用指定时区)
func Now(timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
// 如果时区无效使用UTC
loc, _ = time.LoadLocation(UTC)
}
return time.Now().In(loc)
}
// Parse 解析时间字符串
// layout: 时间格式,如 "2006-01-02 15:04:05"
// value: 时间字符串
// timezone: 时区,如果为空则使用默认时区
func Parse(layout, value string, timezone ...string) (time.Time, error) {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
return time.Time{}, fmt.Errorf("invalid timezone: %w", err)
}
t, err := time.ParseInLocation(layout, value, loc)
if err != nil {
return time.Time{}, fmt.Errorf("failed to parse time: %w", err)
}
return t, nil
}
// Format 格式化时间
// t: 时间对象
// layout: 时间格式,如 "2006-01-02 15:04:05"
// timezone: 时区,如果为空则使用时间对象本身的时区
func Format(t time.Time, layout string, timezone ...string) string {
if len(timezone) > 0 && timezone[0] != "" {
loc, err := GetLocation(timezone[0])
if err == nil {
t = t.In(loc)
}
}
return t.Format(layout)
}
// ToTimezone 将时间转换到指定时区
func ToTimezone(t time.Time, timezone string) (time.Time, error) {
loc, err := GetLocation(timezone)
if err != nil {
return time.Time{}, fmt.Errorf("invalid timezone: %w", err)
}
return t.In(loc), nil
}
// CommonLayouts 常用时间格式
var CommonLayouts = struct {
DateTime string
DateTimeSec string
Date string
Time string
TimeSec string
ISO8601 string
RFC3339 string
RFC3339Nano string
Unix string
}{
DateTime: "2006-01-02 15:04",
DateTimeSec: "2006-01-02 15:04:05",
Date: "2006-01-02",
Time: "15:04",
TimeSec: "15:04:05",
ISO8601: "2006-01-02T15:04:05Z07:00",
RFC3339: time.RFC3339,
RFC3339Nano: time.RFC3339Nano,
Unix: "unix",
}
// FormatDateTime 格式化日期时间2006-01-02 15:04:05
func FormatDateTime(t time.Time, timezone ...string) string {
return Format(t, CommonLayouts.DateTimeSec, timezone...)
}
// FormatDate 格式化日期2006-01-02
func FormatDate(t time.Time, timezone ...string) string {
return Format(t, CommonLayouts.Date, timezone...)
}
// FormatTime 格式化时间15:04:05
func FormatTime(t time.Time, timezone ...string) string {
return Format(t, CommonLayouts.TimeSec, timezone...)
}
// ParseDateTime 解析日期时间字符串2006-01-02 15:04:05
func ParseDateTime(value string, timezone ...string) (time.Time, error) {
return Parse(CommonLayouts.DateTimeSec, value, timezone...)
}
// ParseDate 解析日期字符串2006-01-02
func ParseDate(value string, timezone ...string) (time.Time, error) {
return Parse(CommonLayouts.Date, value, timezone...)
}
// ToUnix 转换为Unix时间戳
func ToUnix(t time.Time) int64 {
return t.Unix()
}
// FromUnix 从Unix时间戳创建时间
func FromUnix(sec int64, timezone ...string) time.Time {
t := time.Unix(sec, 0)
if len(timezone) > 0 && timezone[0] != "" {
loc, err := GetLocation(timezone[0])
if err == nil {
t = t.In(loc)
}
}
return t
}
// ToUnixMilli 转换为Unix毫秒时间戳
func ToUnixMilli(t time.Time) int64 {
return t.UnixMilli()
}
// FromUnixMilli 从Unix毫秒时间戳创建时间
func FromUnixMilli(msec int64, timezone ...string) time.Time {
t := time.UnixMilli(msec)
if len(timezone) > 0 && timezone[0] != "" {
loc, err := GetLocation(timezone[0])
if err == nil {
t = t.In(loc)
}
}
return t
}
// AddDays 添加天数
func AddDays(t time.Time, days int) time.Time {
return t.AddDate(0, 0, days)
}
// AddMonths 添加月数
func AddMonths(t time.Time, months int) time.Time {
return t.AddDate(0, months, 0)
}
// AddYears 添加年数
func AddYears(t time.Time, years int) time.Time {
return t.AddDate(years, 0, 0)
}
// StartOfDay 获取一天的开始时间00:00:00
func StartOfDay(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, month, day := t.Date()
return time.Date(year, month, day, 0, 0, 0, 0, loc)
}
// EndOfDay 获取一天的结束时间23:59:59.999999999
func EndOfDay(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, month, day := t.Date()
return time.Date(year, month, day, 23, 59, 59, 999999999, loc)
}
// StartOfMonth 获取月份的开始时间
func StartOfMonth(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, month, _ := t.Date()
return time.Date(year, month, 1, 0, 0, 0, 0, loc)
}
// EndOfMonth 获取月份的结束时间
func EndOfMonth(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, month, _ := t.Date()
// 获取下个月的第一天然后减去1纳秒
nextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, loc)
return nextMonth.Add(-time.Nanosecond)
}
// StartOfYear 获取年份的开始时间
func StartOfYear(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, _, _ := t.Date()
return time.Date(year, 1, 1, 0, 0, 0, 0, loc)
}
// EndOfYear 获取年份的结束时间
func EndOfYear(t time.Time, timezone ...string) time.Time {
tz := DefaultTimeZone
if len(timezone) > 0 && timezone[0] != "" {
tz = timezone[0]
}
loc, err := GetLocation(tz)
if err != nil {
loc, _ = time.LoadLocation(UTC)
}
t = t.In(loc)
year, _, _ := t.Date()
return time.Date(year, 12, 31, 23, 59, 59, 999999999, loc)
}
// DiffDays 计算两个时间之间的天数差
func DiffDays(t1, t2 time.Time) int {
return int(t2.Sub(t1).Hours() / 24)
}
// DiffHours 计算两个时间之间的小时差
func DiffHours(t1, t2 time.Time) int64 {
return int64(t2.Sub(t1).Hours())
}
// DiffMinutes 计算两个时间之间的分钟差
func DiffMinutes(t1, t2 time.Time) int64 {
return int64(t2.Sub(t1).Minutes())
}
// DiffSeconds 计算两个时间之间的秒数差
func DiffSeconds(t1, t2 time.Time) int64 {
return int64(t2.Sub(t1).Seconds())
}
// ToUTC 将时间转换为UTC时间
// t: 时间对象(可以是任意时区)
// 返回: UTC时间
func ToUTC(t time.Time) time.Time {
return t.UTC()
}
// ToUTCFromTimezone 从指定时区转换为UTC时间
// t: 时间对象(会被视为指定时区的时间)
// timezone: 源时区
// 返回: UTC时间
// 注意此方法假设时间对象t表示的是指定时区的本地时间然后转换为UTC
func ToUTCFromTimezone(t time.Time, timezone string) (time.Time, error) {
loc, err := GetLocation(timezone)
if err != nil {
return time.Time{}, fmt.Errorf("invalid timezone: %w", err)
}
// 将时间视为指定时区的本地时间然后转换为UTC
// 首先将时间转换到指定时区然后转换为UTC
localTime := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), loc)
return localTime.UTC(), nil
}
// ParseToUTC 解析时间字符串并转换为UTC时间
// layout: 时间格式,如 "2006-01-02 15:04:05"
// value: 时间字符串
// timezone: 源时区,如果为空则使用默认时区
// 返回: UTC时间
func ParseToUTC(layout, value string, timezone ...string) (time.Time, error) {
t, err := Parse(layout, value, timezone...)
if err != nil {
return time.Time{}, err
}
return t.UTC(), nil
}
// ParseDateTimeToUTC 解析日期时间字符串并转换为UTC时间便捷方法
// value: 时间字符串(格式: 2006-01-02 15:04:05
// timezone: 源时区,如果为空则使用默认时区
// 返回: UTC时间
func ParseDateTimeToUTC(value string, timezone ...string) (time.Time, error) {
return ParseToUTC(CommonLayouts.DateTimeSec, value, timezone...)
}
// ParseDateToUTC 解析日期字符串并转换为UTC时间便捷方法
// value: 日期字符串(格式: 2006-01-02
// timezone: 源时区,如果为空则使用默认时区
// 返回: UTC时间当天的00:00:00 UTC时间
func ParseDateToUTC(value string, timezone ...string) (time.Time, error) {
return ParseToUTC(CommonLayouts.Date, value, timezone...)
}