初始版本,工具基础类
This commit is contained in:
358
datetime/datetime.go
Normal file
358
datetime/datetime.go
Normal file
@@ -0,0 +1,358 @@
|
||||
package datetime
|
||||
|
||||
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...)
|
||||
}
|
||||
Reference in New Issue
Block a user