Files
go-common/docs/datetime.md

13 KiB
Raw Permalink Blame History

日期转换工具文档

概述

日期转换工具提供了丰富的日期时间处理功能,支持时区设定、格式转换、时间计算等常用操作。

重要说明:日期时间功能位于 tools 包中,推荐通过 factory 包使用(黑盒模式),也可以直接使用 tools 包。

功能特性

  • 支持时区设定和转换
  • 支持多种时间格式的解析和格式化
  • 提供常用时间格式常量
  • 支持Unix时间戳转换
  • 提供时间计算功能(添加天数、月数、年数等)
  • 提供时间范围获取功能(开始/结束时间)
  • 支持将任意时区时间转换为UTC时间用于数据库存储

使用方法

方式1通过 factory 使用(推荐,黑盒模式)

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 包

import "git.toowon.com/jimmy/go-common/tools"

// 设置默认时区为上海时区
err := tools.SetDefaultTimeZone(tools.AsiaShanghai)
if err != nil {
    log.Fatal(err)
}

2. 获取当前时间

通过 factory

// 使用默认时区
now := fac.Now()

// 使用指定时区
now := fac.Now("Asia/Shanghai")
now := fac.Now("America/New_York")

直接使用 tools

// 使用默认时区
now := tools.Now()

// 使用指定时区
now := tools.Now(tools.AsiaShanghai)
now := tools.Now("America/New_York")

3. 解析时间字符串

通过 factory

// 使用默认时区解析
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

// 使用默认时区解析
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

t := time.Now()

// 使用默认时区格式化
str := fac.FormatDateTime(t)
str := fac.FormatDate(t)
str := fac.FormatTime(t)

// 使用指定时区格式化
str := fac.FormatDateTime(t, "Asia/Shanghai")

直接使用 tools

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

t := time.Now()
t2, err := tools.ToTimezone(t, "Asia/Shanghai")

直接使用 tools

t := time.Now()
t2, err := tools.ToTimezone(t, tools.AsiaShanghai)

6. Unix时间戳转换

通过 factory

t := time.Now()

// 转换为Unix时间戳
unix := fac.ToUnix(t)

// 从Unix时间戳创建时间
t2 := fac.FromUnix(unix)

// 转换为Unix毫秒时间戳
unixMilli := fac.ToUnixMilli(t)

// 从Unix毫秒时间戳创建时间
t3 := fac.FromUnixMilli(unixMilli)

直接使用 tools

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

t := time.Now()

// 添加天数
t1 := fac.AddDays(t, 7)

// 添加月数
t2 := fac.AddMonths(t, 1)

// 添加年数
t3 := fac.AddYears(t, 1)

直接使用 tools

t := time.Now()

// 添加天数
t1 := tools.AddDays(t, 7)

// 添加月数
t2 := tools.AddMonths(t, 1)

// 添加年数
t3 := tools.AddYears(t, 1)

8. 时间范围获取

通过 factory

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

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

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

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 暂未提供):

// 将任意时区的时间转换为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 包使用:

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"
)

常用时间格式

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

主要函数

注意:以下函数可以通过 factorytools 包调用。推荐使用 factory 的黑盒模式。

SetDefaultTimeZone(timezone string) error

设置默认时区(仅 tools 包提供)。

参数:

  • timezone: 时区字符串,如 "Asia/Shanghai"

返回: 错误信息

使用方式:

tools.SetDefaultTimeZone(tools.AsiaShanghai)

Now(timezone ...string) time.Time

获取当前时间。

参数:

  • timezone: 可选,时区字符串,不指定则使用默认时区

返回: 时间对象

使用方式:

// 通过 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: 可选,时区字符串

返回: 时间对象和错误信息

使用方式:

// 通过 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: 可选,时区字符串

返回: 格式化后的时间字符串

使用方式:

// 通过 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时间存储
    • 使用ToUTCParseToUTC等方法将时间转换为UTC后存储到数据库
    • 从数据库读取UTC时间后使用ToTimezone转换为用户时区显示

完整示例

示例1通过 factory 使用(推荐)

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 包

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

示例3UTC转换数据库存储场景

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 功能。