Files
go-common/docs/datetime.md

10 KiB
Raw Blame History

日期转换工具文档

概述

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

功能特性

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

使用方法

1. 设置默认时区

import "github.com/go-common/datetime"

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

2. 获取当前时间

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

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

3. 解析时间字符串

// 使用默认时区解析
t, err := datetime.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00")
if err != nil {
    log.Fatal(err)
}

// 使用指定时区解析
t, err := datetime.Parse("2006-01-02 15:04:05", "2024-01-01 12:00:00", datetime.AsiaShanghai)

// 使用常用格式解析
t, err := datetime.ParseDateTime("2024-01-01 12:00:00")
t, err := datetime.ParseDate("2024-01-01")

4. 格式化时间

t := time.Now()

// 使用默认时区格式化
str := datetime.Format(t, "2006-01-02 15:04:05")

// 使用指定时区格式化
str := datetime.Format(t, "2006-01-02 15:04:05", datetime.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"

5. 时区转换

t := time.Now()

// 转换到指定时区
t2, err := datetime.ToTimezone(t, datetime.AsiaShanghai)
if err != nil {
    log.Fatal(err)
}

6. Unix时间戳转换

t := time.Now()

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

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

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

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

7. 时间计算

t := time.Now()

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

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

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

8. 时间范围获取

t := time.Now()

// 获取一天的开始时间00:00:00
start := datetime.StartOfDay(t)

// 获取一天的结束时间23:59:59.999999999
end := datetime.EndOfDay(t)

// 获取月份的开始时间
monthStart := datetime.StartOfMonth(t)

// 获取月份的结束时间
monthEnd := datetime.EndOfMonth(t)

// 获取年份的开始时间
yearStart := datetime.StartOfYear(t)

// 获取年份的结束时间
yearEnd := datetime.EndOfYear(t)

9. 时间差计算

t1 := time.Now()
t2 := time.Now().Add(24 * time.Hour)

// 计算天数差
days := datetime.DiffDays(t1, t2)

// 计算小时差
hours := datetime.DiffHours(t1, t2)

// 计算分钟差
minutes := datetime.DiffMinutes(t1, t2)

// 计算秒数差
seconds := datetime.DiffSeconds(t1, t2)

10. 转换为UTC时间用于数据库存储

// 将任意时区的时间转换为UTC
t := time.Now() // 当前时区的时间
utcTime := datetime.ToUTC(t)

// 从指定时区转换为UTC
t, _ := datetime.ParseDateTime("2024-01-01 12:00:00", datetime.AsiaShanghai)
utcTime, err := datetime.ToUTCFromTimezone(t, datetime.AsiaShanghai)

// 解析时间字符串并直接转换为UTC
utcTime, err := datetime.ParseDateTimeToUTC("2024-01-01 12:00:00", datetime.AsiaShanghai)

// 解析日期并转换为UTC当天的00:00:00 UTC
utcTime, err := datetime.ParseDateToUTC("2024-01-01", datetime.AsiaShanghai)

API 参考

时区常量

const (
    UTC            = "UTC"
    AsiaShanghai   = "Asia/Shanghai"
    AmericaNewYork = "America/New_York"
    EuropeLondon   = "Europe/London"
    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

主要函数

SetDefaultTimeZone(timezone string) error

设置默认时区。

参数:

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

返回: 错误信息

Now(timezone ...string) time.Time

获取当前时间。

参数:

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

返回: 时间对象

Parse(layout, value string, timezone ...string) (time.Time, error)

解析时间字符串。

参数:

  • layout: 时间格式,如 "2006-01-02 15:04:05"
  • value: 时间字符串
  • timezone: 可选,时区字符串

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

Format(t time.Time, layout string, timezone ...string) string

格式化时间。

参数:

  • t: 时间对象
  • layout: 时间格式
  • timezone: 可选,时区字符串

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

ToTimezone(t time.Time, timezone string) (time.Time, error)

转换时区。

参数:

  • 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

计算两个时间之间的秒数差。

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基本使用

package main

import (
    "fmt"
    "log"
    "time"
    
    "github.com/go-common/datetime"
)

func main() {
    // 设置默认时区
    datetime.SetDefaultTimeZone(datetime.AsiaShanghai)
    
    // 获取当前时间
    now := datetime.Now()
    fmt.Printf("Current time: %s\n", datetime.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))
}

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

package main

import (
    "fmt"
    "log"
    
    "github.com/go-common/datetime"
)

func main() {
    // 从请求中获取时间(假设是上海时区)
    requestTimeStr := "2024-01-01 12:00:00"
    requestTimezone := datetime.AsiaShanghai
    
    // 转换为UTC时间用于数据库存储
    dbTime, err := datetime.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))
    
    // 从数据库读取UTC时间转换为用户时区显示
    userTimezone := datetime.AsiaShanghai
    displayTime, err := datetime.ToTimezone(dbTime, userTimezone)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Display time (Shanghai): %s\n", datetime.FormatDateTime(displayTime, userTimezone))
}

完整示例请参考:

  • examples/datetime_example.go - 基本使用示例
  • examples/datetime_utc_example.go - UTC转换示例