调整项目结构,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

View File

@@ -4,6 +4,8 @@
日期转换工具提供了丰富的日期时间处理功能,支持时区设定、格式转换、时间计算等常用操作。
**重要说明**:日期时间功能位于 `tools` 包中,推荐通过 `factory` 包使用(黑盒模式),也可以直接使用 `tools` 包。
## 功能特性
- 支持时区设定和转换
@@ -16,13 +18,34 @@
## 使用方法
### 1. 设置默认时区
### 方式1通过 factory 使用(推荐,黑盒模式)
```go
import "git.toowon.com/jimmy/go-common/datetime"
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 := datetime.SetDefaultTimeZone(datetime.AsiaShanghai)
err := tools.SetDefaultTimeZone(tools.AsiaShanghai)
if err != nil {
log.Fatal(err)
}
@@ -30,166 +53,284 @@ if err != nil {
### 2. 获取当前时间
**通过 factory**
```go
// 使用默认时区
now := datetime.Now()
now := fac.Now()
// 使用指定时区
now := datetime.Now(datetime.AsiaShanghai)
now := datetime.Now("America/New_York")
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 := datetime.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00")
if err != nil {
log.Fatal(err)
}
t, err := fac.ParseDateTime("2024-01-01 12:00:00")
// 使用指定时区解析
t, err := datetime.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00", datetime.AsiaShanghai)
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 := datetime.ParseDateTime("2024-01-01 12:00:00")
t, err := datetime.ParseDate("2024-01-01")
t, err := tools.ParseDateTime("2024-01-01 12:00:00")
t, err := tools.ParseDate("2024-01-01")
```
### 4. 格式化时间
**通过 factory**
```go
t := time.Now()
// 使用默认时区格式化
str := datetime.Format(t, "2006-01-02 15:04:05")
str := fac.FormatDateTime(t)
str := fac.FormatDate(t)
str := fac.FormatTime(t)
// 使用指定时区格式化
str := datetime.Format(t, "2006-01-02 15:04:05", datetime.AsiaShanghai)
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 := datetime.FormatDateTime(t) // "2006-01-02 15:04:05"
str := datetime.FormatDate(t) // "2006-01-02"
str := datetime.FormatTime(t) // "15:04:05"
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")
```
// 转换到指定时区
t2, err := datetime.ToTimezone(t, datetime.AsiaShanghai)
if err != nil {
log.Fatal(err)
}
**直接使用 tools**
```go
t := time.Now()
t2, err := tools.ToTimezone(t, tools.AsiaShanghai)
```
### 6. Unix时间戳转换
**通过 factory**
```go
t := time.Now()
// 转换为Unix时间戳
unix := datetime.ToUnix(t)
unix := fac.ToUnix(t)
// 从Unix时间戳创建时间
t2 := datetime.FromUnix(unix)
t2 := fac.FromUnix(unix)
// 转换为Unix毫秒时间戳
unixMilli := datetime.ToUnixMilli(t)
unixMilli := fac.ToUnixMilli(t)
// 从Unix毫秒时间戳创建时间
t3 := datetime.FromUnixMilli(unixMilli)
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 := datetime.AddDays(t, 7)
t1 := fac.AddDays(t, 7)
// 添加月数
t2 := datetime.AddMonths(t, 1)
t2 := fac.AddMonths(t, 1)
// 添加年数
t3 := datetime.AddYears(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 := datetime.StartOfDay(t)
start := fac.StartOfDay(t)
// 获取一天的结束时间23:59:59.999999999
end := datetime.EndOfDay(t)
end := fac.EndOfDay(t)
// 获取月份的开始时间
monthStart := datetime.StartOfMonth(t)
monthStart := fac.StartOfMonth(t)
// 获取月份的结束时间
monthEnd := datetime.EndOfMonth(t)
monthEnd := fac.EndOfMonth(t)
// 获取年份的开始时间
yearStart := datetime.StartOfYear(t)
yearStart := fac.StartOfYear(t)
// 获取年份的结束时间
yearEnd := datetime.EndOfYear(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 := datetime.DiffDays(t1, t2)
days := fac.DiffDays(t1, t2)
// 计算小时差
hours := datetime.DiffHours(t1, t2)
hours := fac.DiffHours(t1, t2)
// 计算分钟差
minutes := datetime.DiffMinutes(t1, t2)
minutes := fac.DiffMinutes(t1, t2)
// 计算秒数差
seconds := datetime.DiffSeconds(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时间用于数据库存储
**直接使用 toolsfactory 暂未提供):**
```go
// 将任意时区的时间转换为UTC
t := time.Now() // 当前时区的时间
utcTime := datetime.ToUTC(t)
utcTime := tools.ToUTC(t)
// 从指定时区转换为UTC
t, _ := datetime.ParseDateTime("2024-01-01 12:00:00", datetime.AsiaShanghai)
utcTime, err := datetime.ToUTCFromTimezone(t, datetime.AsiaShanghai)
t, _ := tools.ParseDateTime("2024-01-01 12:00:00", tools.AsiaShanghai)
utcTime, err := tools.ToUTCFromTimezone(t, tools.AsiaShanghai)
// 解析时间字符串并直接转换为UTC
utcTime, err := datetime.ParseDateTimeToUTC("2024-01-01 12:00:00", datetime.AsiaShanghai)
utcTime, err := tools.ParseDateTimeToUTC("2024-01-01 12:00:00", tools.AsiaShanghai)
// 解析日期并转换为UTC当天的00:00:00 UTC
utcTime, err := datetime.ParseDateToUTC("2024-01-01", datetime.AsiaShanghai)
utcTime, err := tools.ParseDateToUTC("2024-01-01", tools.AsiaShanghai)
```
## API 参考
### 时区常量
**通过 tools 包使用:**
```go
import "git.toowon.com/jimmy/go-common/tools"
const (
UTC = "UTC"
AsiaShanghai = "Asia/Shanghai"
AmericaNewYork = "America/New_York"
EuropeLondon = "Europe/London"
AsiaTokyo = "Asia/Tokyo"
tools.UTC = "UTC"
tools.AsiaShanghai = "Asia/Shanghai"
tools.AmericaNewYork = "America/New_York"
tools.EuropeLondon = "Europe/London"
tools.AsiaTokyo = "Asia/Tokyo"
)
```
@@ -208,15 +349,22 @@ 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
获取当前时间。
@@ -226,105 +374,54 @@ CommonLayouts.RFC3339Nano = time.RFC3339Nano
**返回:** 时间对象
#### Parse(layout, value string, timezone ...string) (time.Time, error)
**使用方式:**
```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
**参数:**
- `layout`: 时间格式,如 "2006-01-02 15:04:05"
- `value`: 时间字符串
- `timezone`: 可选,时区字符串
**返回:** 时间对象和错误信息
#### Format(t time.Time, layout string, timezone ...string) string
**使用方式:**
```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`: 时间对象
- `layout`: 时间格式
- `timezone`: 可选,时区字符串
**返回:** 格式化后的时间字符串
#### ToTimezone(t time.Time, timezone string) (time.Time, error)
**使用方式:**
```go
// 通过 factory
str := fac.FormatDateTime(t, "Asia/Shanghai")
转换时区。
// 直接使用 tools
str := tools.FormatDateTime(t, tools.AsiaShanghai)
```
**参数:**
- `t`: 时间对象
- `timezone`: 目标时区
**返回:** 转换后的时间对象和错误信息
#### ToUnix(t time.Time) int64
转换为Unix时间戳
#### FromUnix(sec int64, timezone ...string) time.Time
从Unix时间戳创建时间。
#### ToUnixMilli(t time.Time) int64
转换为Unix毫秒时间戳。
#### FromUnixMilli(msec int64, timezone ...string) time.Time
从Unix毫秒时间戳创建时间。
#### AddDays(t time.Time, days int) time.Time
添加天数。
#### AddMonths(t time.Time, months int) time.Time
添加月数。
#### AddYears(t time.Time, years int) time.Time
添加年数。
#### StartOfDay(t time.Time, timezone ...string) time.Time
获取一天的开始时间。
#### EndOfDay(t time.Time, timezone ...string) time.Time
获取一天的结束时间。
#### StartOfMonth(t time.Time, timezone ...string) time.Time
获取月份的开始时间。
#### EndOfMonth(t time.Time, timezone ...string) time.Time
获取月份的结束时间。
#### StartOfYear(t time.Time, timezone ...string) time.Time
获取年份的开始时间。
#### EndOfYear(t time.Time, timezone ...string) time.Time
获取年份的结束时间。
#### DiffDays(t1, t2 time.Time) int
计算两个时间之间的天数差。
#### DiffHours(t1, t2 time.Time) int64
计算两个时间之间的小时差。
#### DiffMinutes(t1, t2 time.Time) int64
计算两个时间之间的分钟差。
#### DiffSeconds(t1, t2 time.Time) int64
计算两个时间之间的秒数差。
更多函数请参考 `factory` 包或 `tools` 包的 API 文档。
### UTC转换函数
@@ -391,7 +488,7 @@ CommonLayouts.RFC3339Nano = time.RFC3339Nano
## 完整示例
### 示例1基本使用
### 示例1通过 factory 使用(推荐)
```go
package main
@@ -399,27 +496,67 @@ package main
import (
"fmt"
"log"
"time"
"git.toowon.com/jimmy/go-common/datetime"
"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() {
// 设置默认时区
datetime.SetDefaultTimeZone(datetime.AsiaShanghai)
err := tools.SetDefaultTimeZone(tools.AsiaShanghai)
if err != nil {
log.Fatal(err)
}
// 获取当前时间
now := datetime.Now()
fmt.Printf("Current time: %s\n", datetime.FormatDateTime(now))
now := tools.Now()
fmt.Printf("Current time: %s\n", tools.FormatDateTime(now))
// 时区转换
t, _ := datetime.ParseDateTime("2024-01-01 12:00:00")
t2, _ := datetime.ToTimezone(t, datetime.AmericaNewYork)
fmt.Printf("Time in New York: %s\n", datetime.FormatDateTime(t2))
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))
}
```
### 示例2UTC转换数据库存储场景
### 示例3UTC转换数据库存储场景
```go
package main
@@ -428,34 +565,32 @@ import (
"fmt"
"log"
"git.toowon.com/jimmy/go-common/datetime"
"git.toowon.com/jimmy/go-common/tools"
)
func main() {
// 从请求中获取时间(假设是上海时区)
requestTimeStr := "2024-01-01 12:00:00"
requestTimezone := datetime.AsiaShanghai
requestTimezone := tools.AsiaShanghai
// 转换为UTC时间用于数据库存储
dbTime, err := datetime.ParseDateTimeToUTC(requestTimeStr, requestTimezone)
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", datetime.FormatDateTime(dbTime, datetime.UTC))
fmt.Printf("Database time (UTC): %s\n", tools.FormatDateTime(dbTime, tools.UTC))
// 从数据库读取UTC时间转换为用户时区显示
userTimezone := datetime.AsiaShanghai
displayTime, err := datetime.ToTimezone(dbTime, userTimezone)
userTimezone := tools.AsiaShanghai
displayTime, err := tools.ToTimezone(dbTime, userTimezone)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Display time (Shanghai): %s\n", datetime.FormatDateTime(displayTime, userTimezone))
fmt.Printf("Display time (Shanghai): %s\n", tools.FormatDateTime(displayTime, userTimezone))
}
```
完整示例请参考
- `examples/datetime_example.go` - 基本使用示例
- `examples/datetime_utc_example.go` - UTC转换示例
完整示例请参考 `factory` 包中的 datetime 相关方法,通过 `factory` 调用 `tools` 包中的 datetime 功能。