# 日期转换工具文档 ## 概述 日期转换工具提供了丰富的日期时间处理功能,支持时区设定、格式转换、时间计算等常用操作。 **重要说明**:日期时间功能位于 `tools` 包中,推荐通过 `factory` 包使用(黑盒模式),也可以直接使用 `tools` 包。 ## 功能特性 - 支持时区设定和转换 - 支持多种时间格式的解析和格式化 - 提供常用时间格式常量 - 支持Unix时间戳转换 - 提供时间计算功能(添加天数、月数、年数等) - 提供时间范围获取功能(开始/结束时间) - 支持将任意时区时间转换为UTC时间(用于数据库存储) ## 使用方法 ### 方式1:通过 factory 使用(推荐,黑盒模式) ```go import "git.toowon.com/jimmy/go-common/factory" // 创建工厂 fac, _ := factory.NewFactoryFromFile("config.json") // 获取当前时间 now := fac.Now("Asia/Shanghai") // 格式化时间 str := fac.FormatDateTime(now) // 解析时间 t, _ := fac.ParseDateTime("2024-01-01 12:00:00", "Asia/Shanghai") // 时间计算 tomorrow := fac.AddDays(now, 1) ``` ### 方式2:直接使用 tools 包 ```go import "git.toowon.com/jimmy/go-common/tools" // 设置默认时区为上海时区 err := tools.SetDefaultTimeZone(tools.AsiaShanghai) if err != nil { log.Fatal(err) } ``` ### 2. 获取当前时间 **通过 factory:** ```go // 使用默认时区 now := fac.Now() // 使用指定时区 now := fac.Now("Asia/Shanghai") now := fac.Now("America/New_York") ``` **直接使用 tools:** ```go // 使用默认时区 now := tools.Now() // 使用指定时区 now := tools.Now(tools.AsiaShanghai) now := tools.Now("America/New_York") ``` ### 3. 解析时间字符串 **通过 factory:** ```go // 使用默认时区解析 t, err := fac.ParseDateTime("2024-01-01 12:00:00") // 使用指定时区解析 t, err := fac.ParseDateTime("2024-01-01 12:00:00", "Asia/Shanghai") // 解析日期 t, err := fac.ParseDate("2024-01-01") ``` **直接使用 tools:** ```go // 使用默认时区解析 t, err := tools.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00") // 使用指定时区解析 t, err := tools.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00", tools.AsiaShanghai) // 使用常用格式解析 t, err := tools.ParseDateTime("2024-01-01 12:00:00") t, err := tools.ParseDate("2024-01-01") ``` ### 4. 格式化时间 **通过 factory:** ```go t := time.Now() // 使用默认时区格式化 str := fac.FormatDateTime(t) str := fac.FormatDate(t) str := fac.FormatTime(t) // 使用指定时区格式化 str := fac.FormatDateTime(t, "Asia/Shanghai") ``` **直接使用 tools:** ```go t := time.Now() // 使用默认时区格式化 str := tools.Format(t, "2006-01-02 15:04:05") // 使用指定时区格式化 str := tools.Format(t, "2006-01-02 15:04:05", tools.AsiaShanghai) // 使用常用格式 str := tools.FormatDateTime(t) // "2006-01-02 15:04:05" str := tools.FormatDate(t) // "2006-01-02" str := tools.FormatTime(t) // "15:04:05" ``` ### 5. 时区转换 **通过 factory:** ```go t := time.Now() t2, err := tools.ToTimezone(t, "Asia/Shanghai") ``` **直接使用 tools:** ```go t := time.Now() t2, err := tools.ToTimezone(t, tools.AsiaShanghai) ``` ### 6. Unix时间戳转换 **通过 factory:** ```go t := time.Now() // 转换为Unix时间戳(秒) unix := fac.ToUnix(t) // 从Unix时间戳创建时间 t2 := fac.FromUnix(unix) // 转换为Unix毫秒时间戳 unixMilli := fac.ToUnixMilli(t) // 从Unix毫秒时间戳创建时间 t3 := fac.FromUnixMilli(unixMilli) ``` **直接使用 tools:** ```go t := time.Now() // 转换为Unix时间戳(秒) unix := tools.ToUnix(t) // 从Unix时间戳创建时间 t2 := tools.FromUnix(unix) // 转换为Unix毫秒时间戳 unixMilli := tools.ToUnixMilli(t) // 从Unix毫秒时间戳创建时间 t3 := tools.FromUnixMilli(unixMilli) ``` ### 7. 时间计算 **通过 factory:** ```go t := time.Now() // 添加天数 t1 := fac.AddDays(t, 7) // 添加月数 t2 := fac.AddMonths(t, 1) // 添加年数 t3 := fac.AddYears(t, 1) ``` **直接使用 tools:** ```go t := time.Now() // 添加天数 t1 := tools.AddDays(t, 7) // 添加月数 t2 := tools.AddMonths(t, 1) // 添加年数 t3 := tools.AddYears(t, 1) ``` ### 8. 时间范围获取 **通过 factory:** ```go t := time.Now() // 获取一天的开始时间(00:00:00) start := fac.StartOfDay(t) // 获取一天的结束时间(23:59:59.999999999) end := fac.EndOfDay(t) // 获取月份的开始时间 monthStart := fac.StartOfMonth(t) // 获取月份的结束时间 monthEnd := fac.EndOfMonth(t) // 获取年份的开始时间 yearStart := fac.StartOfYear(t) // 获取年份的结束时间 yearEnd := fac.EndOfYear(t) ``` **直接使用 tools:** ```go t := time.Now() // 获取一天的开始时间(00:00:00) start := tools.StartOfDay(t) // 获取一天的结束时间(23:59:59.999999999) end := tools.EndOfDay(t) // 获取月份的开始时间 monthStart := tools.StartOfMonth(t) // 获取月份的结束时间 monthEnd := tools.EndOfMonth(t) // 获取年份的开始时间 yearStart := tools.StartOfYear(t) // 获取年份的结束时间 yearEnd := tools.EndOfYear(t) ``` ### 9. 时间差计算 **通过 factory:** ```go t1 := time.Now() t2 := time.Now().Add(24 * time.Hour) // 计算天数差 days := fac.DiffDays(t1, t2) // 计算小时差 hours := fac.DiffHours(t1, t2) // 计算分钟差 minutes := fac.DiffMinutes(t1, t2) // 计算秒数差 seconds := fac.DiffSeconds(t1, t2) ``` **直接使用 tools:** ```go t1 := time.Now() t2 := time.Now().Add(24 * time.Hour) // 计算天数差 days := tools.DiffDays(t1, t2) // 计算小时差 hours := tools.DiffHours(t1, t2) // 计算分钟差 minutes := tools.DiffMinutes(t1, t2) // 计算秒数差 seconds := tools.DiffSeconds(t1, t2) ``` ### 10. 转换为UTC时间(用于数据库存储) **直接使用 tools(factory 暂未提供):** ```go // 将任意时区的时间转换为UTC t := time.Now() // 当前时区的时间 utcTime := tools.ToUTC(t) // 从指定时区转换为UTC t, _ := tools.ParseDateTime("2024-01-01 12:00:00", tools.AsiaShanghai) utcTime, err := tools.ToUTCFromTimezone(t, tools.AsiaShanghai) // 解析时间字符串并直接转换为UTC utcTime, err := tools.ParseDateTimeToUTC("2024-01-01 12:00:00", tools.AsiaShanghai) // 解析日期并转换为UTC(当天的00:00:00 UTC) utcTime, err := tools.ParseDateToUTC("2024-01-01", tools.AsiaShanghai) ``` ## API 参考 ### 时区常量 **通过 tools 包使用:** ```go import "git.toowon.com/jimmy/go-common/tools" const ( tools.UTC = "UTC" tools.AsiaShanghai = "Asia/Shanghai" tools.AmericaNewYork = "America/New_York" tools.EuropeLondon = "Europe/London" tools.AsiaTokyo = "Asia/Tokyo" ) ``` ### 常用时间格式 ```go CommonLayouts.DateTime = "2006-01-02 15:04" CommonLayouts.DateTimeSec = "2006-01-02 15:04:05" CommonLayouts.Date = "2006-01-02" CommonLayouts.Time = "15:04" CommonLayouts.TimeSec = "15:04:05" CommonLayouts.ISO8601 = "2006-01-02T15:04:05Z07:00" CommonLayouts.RFC3339 = time.RFC3339 CommonLayouts.RFC3339Nano = time.RFC3339Nano ``` ### 主要函数 **注意**:以下函数可以通过 `factory` 或 `tools` 包调用。推荐使用 `factory` 的黑盒模式。 #### SetDefaultTimeZone(timezone string) error 设置默认时区(仅 tools 包提供)。 **参数:** - `timezone`: 时区字符串,如 "Asia/Shanghai" **返回:** 错误信息 **使用方式:** ```go tools.SetDefaultTimeZone(tools.AsiaShanghai) ``` #### Now(timezone ...string) time.Time 获取当前时间。 **参数:** - `timezone`: 可选,时区字符串,不指定则使用默认时区 **返回:** 时间对象 **使用方式:** ```go // 通过 factory now := fac.Now("Asia/Shanghai") // 直接使用 tools now := tools.Now(tools.AsiaShanghai) ``` #### ParseDateTime(value string, timezone ...string) (time.Time, error) 解析日期时间字符串(2006-01-02 15:04:05)。 **参数:** - `value`: 时间字符串 - `timezone`: 可选,时区字符串 **返回:** 时间对象和错误信息 **使用方式:** ```go // 通过 factory t, err := fac.ParseDateTime("2024-01-01 12:00:00", "Asia/Shanghai") // 直接使用 tools t, err := tools.ParseDateTime("2024-01-01 12:00:00", tools.AsiaShanghai) ``` #### FormatDateTime(t time.Time, timezone ...string) string 格式化日期时间(2006-01-02 15:04:05)。 **参数:** - `t`: 时间对象 - `timezone`: 可选,时区字符串 **返回:** 格式化后的时间字符串 **使用方式:** ```go // 通过 factory str := fac.FormatDateTime(t, "Asia/Shanghai") // 直接使用 tools str := tools.FormatDateTime(t, tools.AsiaShanghai) ``` 更多函数请参考 `factory` 包或 `tools` 包的 API 文档。 ### UTC转换函数 #### ToUTC(t time.Time) time.Time 将时间转换为UTC时间。 **参数:** - `t`: 时间对象(可以是任意时区) **返回:** UTC时间 #### ToUTCFromTimezone(t time.Time, timezone string) (time.Time, error) 从指定时区转换为UTC时间。 **参数:** - `t`: 时间对象(会被视为指定时区的时间) - `timezone`: 源时区 **返回:** UTC时间和错误信息 #### ParseToUTC(layout, value string, timezone ...string) (time.Time, error) 解析时间字符串并转换为UTC时间。 **参数:** - `layout`: 时间格式,如 "2006-01-02 15:04:05" - `value`: 时间字符串 - `timezone`: 源时区,如果为空则使用默认时区 **返回:** UTC时间和错误信息 #### ParseDateTimeToUTC(value string, timezone ...string) (time.Time, error) 解析日期时间字符串并转换为UTC时间(便捷方法)。 **参数:** - `value`: 时间字符串(格式: 2006-01-02 15:04:05) - `timezone`: 源时区,如果为空则使用默认时区 **返回:** UTC时间和错误信息 #### ParseDateToUTC(value string, timezone ...string) (time.Time, error) 解析日期字符串并转换为UTC时间(便捷方法)。 **参数:** - `value`: 日期字符串(格式: 2006-01-02) - `timezone`: 源时区,如果为空则使用默认时区 **返回:** UTC时间(当天的00:00:00 UTC时间)和错误信息 ## 注意事项 1. **时区字符串**:必须符合IANA时区数据库格式 2. **默认时区**:默认时区为UTC,建议在应用启动时设置合适的默认时区 3. **时间格式**:时间格式字符串必须使用Go的特定时间(2006-01-02 15:04:05) 4. **时间范围函数**:所有时间范围函数(StartOfDay、EndOfDay等)都会考虑时区 5. **数据库存储**: - 数据库时间统一使用UTC时间存储 - 使用`ToUTC`、`ParseToUTC`等方法将时间转换为UTC后存储到数据库 - 从数据库读取UTC时间后,使用`ToTimezone`转换为用户时区显示 ## 完整示例 ### 示例1:通过 factory 使用(推荐) ```go package main import ( "fmt" "log" "git.toowon.com/jimmy/go-common/factory" ) func main() { // 创建工厂 fac, err := factory.NewFactoryFromFile("config.json") if err != nil { log.Fatal(err) } // 获取当前时间 now := fac.Now("Asia/Shanghai") fmt.Printf("Current time: %s\n", fac.FormatDateTime(now)) // 解析时间 t, err := fac.ParseDateTime("2024-01-01 12:00:00", "Asia/Shanghai") if err != nil { log.Fatal(err) } // 格式化时间 fmt.Printf("Parsed time: %s\n", fac.FormatDateTime(t)) // 时间计算 tomorrow := fac.AddDays(now, 1) fmt.Printf("Tomorrow: %s\n", fac.FormatDate(tomorrow)) } ``` ### 示例2:直接使用 tools 包 ```go package main import ( "fmt" "log" "git.toowon.com/jimmy/go-common/tools" ) func main() { // 设置默认时区 err := tools.SetDefaultTimeZone(tools.AsiaShanghai) if err != nil { log.Fatal(err) } // 获取当前时间 now := tools.Now() fmt.Printf("Current time: %s\n", tools.FormatDateTime(now)) // 时区转换 t, _ := tools.ParseDateTime("2024-01-01 12:00:00") t2, _ := tools.ToTimezone(t, tools.AmericaNewYork) fmt.Printf("Time in New York: %s\n", tools.FormatDateTime(t2)) } ``` ### 示例3:UTC转换(数据库存储场景) ```go package main import ( "fmt" "log" "git.toowon.com/jimmy/go-common/tools" ) func main() { // 从请求中获取时间(假设是上海时区) requestTimeStr := "2024-01-01 12:00:00" requestTimezone := tools.AsiaShanghai // 转换为UTC时间(用于数据库存储) dbTime, err := tools.ParseDateTimeToUTC(requestTimeStr, requestTimezone) if err != nil { log.Fatal(err) } fmt.Printf("Request time (Shanghai): %s\n", requestTimeStr) fmt.Printf("Database time (UTC): %s\n", tools.FormatDateTime(dbTime, tools.UTC)) // 从数据库读取UTC时间,转换为用户时区显示 userTimezone := tools.AsiaShanghai displayTime, err := tools.ToTimezone(dbTime, userTimezone) if err != nil { log.Fatal(err) } fmt.Printf("Display time (Shanghai): %s\n", tools.FormatDateTime(displayTime, userTimezone)) } ``` 完整示例请参考 `factory` 包中的 datetime 相关方法,通过 `factory` 调用 `tools` 包中的 datetime 功能。