voucher/internal/pkg/helper/datetime.go

260 lines
7.2 KiB
Go
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package helper
import (
"fmt"
"time"
"github.com/pkg/errors"
"google.golang.org/protobuf/types/known/timestamppb"
)
const (
DefaultParseFormatLayout = "2006-1-02 15:04:05" // 默认解析时间格式
DefaultFormatLayout = "2006-01-02 15:04:05" // 默认时间格式
MicroFormatLayout = "2006-01-02 15:04:05.000000" // 微秒时间格式
FormatLayout = "20060102150405" // 导出时间格式
)
func AfterMinutesUnix(minutes int64) int64 {
// 获取当前时间
currentTime := time.Now()
// 将当前时间增加5分钟
currentTime = currentTime.Add(time.Duration(minutes) * time.Minute)
// 转换为Unix时间戳
return currentTime.Unix()
}
func Parse(inputTime string) (time.Time, error) {
// 设置时区为中国上海
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
return time.Time{}, err
}
// 解析时间字符串并指定时区
parsedTime, err := time.ParseInLocation("2006-01-02 15:04:05", inputTime, loc)
if err != nil {
return time.Time{}, err
}
return parsedTime, nil
}
func Parse2(timeStr string) (time.Time, error) {
//if timeStr == "" {
// return time.Time{}, fmt.Errorf("时间参数未传递")
//}
//timeStr = strings.Replace(timeStr, "+", " ", -1)
// 解析日期时间字符串
t, err := time.Parse(DefaultFormatLayout, timeStr)
if err != nil {
return time.Time{}, err
}
// 获取本地时区的 *time.Location 对象
local := time.Now().Location()
// 将时间转换为本地时区的时间
localTime := t.In(local)
return localTime, nil
}
func DateStringToTime(localTimeStr string) (time.Time, error) {
if localTimeStr == "" {
return time.Time{}, fmt.Errorf("时间参数未传递")
}
layouts := []string{
DefaultParseFormatLayout,
DefaultFormatLayout,
"2006-01-02 15:04",
"2006-1-02 15:04",
"2006-01-02",
"2006-1-02",
time.RFC3339Nano,
}
var (
localTime time.Time
err error
)
loc, _ := time.LoadLocation(GetTimeZone())
for _, layout := range layouts {
localTime, err = time.ParseInLocation(layout, localTimeStr, loc)
if err == nil {
break
}
}
if err != nil {
return time.Time{}, fmt.Errorf("时间转换错误:%v", err)
}
return localTime, nil
}
// TimeFormat 时间戳转时间格式
func TimeFormat(inTime *time.Time, layout ...string) string {
if inTime == nil {
return ""
}
if len(layout) == 0 {
layout = []string{DefaultFormatLayout}
}
return inTime.Format(layout[0])
}
// TimeStampFormat 时间戳转时间格式
func TimeStampFormat(timestamp int64, layout ...string) string {
if timestamp == 0 {
return ""
}
if len(layout) == 0 {
layout = []string{DefaultFormatLayout}
}
return time.Unix(timestamp, 0).Format(layout[0])
}
// Int32TimeStampFormat int32类型时间戳转时间格式
func Int32TimeStampFormat(timestamp int32, layout ...string) string {
return TimeStampFormat(int64(timestamp), layout...)
}
// IsoDateStringToTimeStamp iso格式字符串转时间戳
func IsoDateStringToTimeStamp(isoTimeStr string) (int64, error) {
isoTime, err := time.ParseInLocation(time.RFC3339Nano, isoTimeStr, time.Local)
if err != nil {
return 0, err
}
return isoTime.Unix(), nil
}
// LayOutDateStringToTimeStamp layout格式字符串转时间戳
func LayOutDateStringToTimeStamp(localTimeStr string) (int64, error) {
localTime, err := time.ParseInLocation(DefaultFormatLayout, localTimeStr, time.Local)
if err != nil {
return 0, err
}
return localTime.Unix(), nil
}
// DateStringToTimeStamp 字符串转时间戳(兼容格式)
func DateStringToTimeStamp(date string) (int64, error) {
u, err := IsoDateStringToTimeStamp(date)
if err != nil {
u, err = LayOutDateStringToTimeStamp(date)
}
return u, err
}
// DateStringToTimeStampInt32 字符串转时间戳(兼容格式)
func DateStringToTimeStampInt32(date string) (int32, error) {
u, err := DateStringToTimeStamp(date)
return int32(u), err
}
// BatchDateStringToTimeStampInt32 批量字符串转时间戳
func BatchDateStringToTimeStampInt32(dates []string) ([]int32, error) {
res := make([]int32, 0, len(dates))
for _, date := range dates {
u, err := DateStringToTimeStampInt32(date)
if err != nil {
return nil, err
}
res = append(res, u)
}
return res, nil
}
// GoogleTimeToString google proto时间转字符串
func GoogleTimeToString(date *timestamppb.Timestamp) string {
loc, _ := time.LoadLocation(GetTimeZone())
return date.AsTime().In(loc).Format(DefaultFormatLayout)
}
// GoogleTimeToMicroString google proto时间转字符串
func GoogleTimeToMicroString(date *timestamppb.Timestamp) string {
loc, _ := time.LoadLocation(GetTimeZone())
return date.AsTime().In(loc).Format(MicroFormatLayout)
}
func DateStringToTimeStampV2(localTimeStr string) (int64, error) {
if localTimeStr == "" {
return 0, nil
}
layouts := []string{
DefaultParseFormatLayout,
DefaultFormatLayout,
"2006-01-02 15:04",
"2006-1-02 15:04",
"2006-01-02",
"2006-1-02",
time.RFC3339Nano,
}
var (
localTime time.Time
err error
)
loc, _ := time.LoadLocation(GetTimeZone())
for _, layout := range layouts {
localTime, err = time.ParseInLocation(layout, localTimeStr, loc)
if err == nil {
break
}
}
if err != nil {
return 0, errors.Errorf("解析时间错误: %s", err.Error())
}
return localTime.Unix(), nil
}
// IsTimeStrBefore 时间比较 格式2006-01-02 15:04:05
func IsTimeStrBefore(beforeTime, afterTime string) bool {
time1, _ := time.Parse(DefaultFormatLayout, beforeTime)
time2, _ := time.Parse(DefaultFormatLayout, afterTime)
if time1.Before(time2) {
return true
}
return false
}
// IsTimeBefore 时间比较 格式2006-01-02 15:04:05,beforeTime[2024-01-10 00:00:00]小于afterTime[2024-01-02 00:00:00]返回true
func IsTimeBefore(beforeTime, afterTime time.Time) bool {
if beforeTime.Before(afterTime) {
return true
}
return false
}
// IsTimeBeforeOrEqual 时间比较 格式2006-01-02 15:04:05,beforeTime[2024-01-10 00:00:00]小于等于afterTime[2024-01-02 00:00:00]返回true
func IsTimeBeforeOrEqual(beforeTime, afterTime time.Time) bool {
b := beforeTime.Before(afterTime) || beforeTime.Equal(afterTime)
if b {
return true
}
return false
}
// IsInSameNaturalMonth 判断两个时间是否在同一个自然月
func IsInSameNaturalMonth(startTime, endTime time.Time) bool {
// 将 startTime 和 endTime 的日期统一到该月的12号
startYear, startMonth, _ := startTime.Date()
endYear, endMonth, _ := endTime.Date()
// 如果月份不同,调整 endTime 到 startTime 的同一天(同月)
if startYear == endYear && startMonth == endMonth {
return true
}
// 处理跨月情况, 检查如果 startTime 和 endTime 跨越到下一个月的同一天
// 比如:如果 startTime 是 12 号,则 endTime 应该是下个月的12号
expectedEndTime := time.Date(endYear, endMonth, startTime.Day(), startTime.Hour(), startTime.Minute(), startTime.Second(), 0, time.Local)
// 如果 endTime 的日期和调整后的 expectedEndTime 相同,则认为它们属于同一个自然月
return expectedEndTime.Year() == endTime.Year() &&
expectedEndTime.Month() == endTime.Month() &&
expectedEndTime.Day() == endTime.Day() &&
expectedEndTime.Hour() == endTime.Hour() &&
expectedEndTime.Minute() == endTime.Minute() &&
expectedEndTime.Second() == endTime.Second()
}