1 Star 5 Fork 0

A-涛/gotool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
date.go 10.96 KB
一键复制 编辑 原始数据 按行查看 历史
A-涛 提交于 2023-01-07 11:19 . update GetTimeFmt
package base
import (
"strconv"
"strings"
"time"
"gitee.com/xuesongtao/gotool/internal"
)
const (
DayInt = 24 * 3600
DayDur = 24 * time.Hour
StartTimeSuffix = " 00:00:00"
EndTimeSuffix = " 23:59:59"
GetDateBetweenForDate int32 = 1 // 按日处理
GetDateBetweenForMonth int32 = 2 // 按月处理
GetDateBetweenForYear int32 = 3 // 按年处理
)
const (
// 时间格式
YearFmt int8 = 1 << iota
MonthFmt
DayFmt
HourFmt
MinFmt
SecFmt
MilliFmt // 毫秒
DateFmtFlag = YearFmt | MonthFmt | DayFmt
DateTimeFmtFlag = DateFmtFlag | HourFmt | MinFmt | SecFmt
MilliDateTimeFmtFlag = DateFmtFlag | HourFmt | MinFmt | SecFmt | MilliFmt
)
var (
DateFmt = GetTimeFmt(DateFmtFlag) // 2006-01-02
DatetimeFmt = GetTimeFmt(DateTimeFmtFlag) // 2006-01-02 15:04:05
)
type weekInfo struct {
StartTimeObj time.Time // 本周的最开始对象
EndTimeObj time.Time // 本周的结束对象
StartDate string // 本周开始日期
EndDate string // 本周结束日期
Dates []string // 日期
Date2WeekMap map[string]string // 保存的日期对应的星期几, map[2021-09-01]星期一
}
// FormatBusinessDate 将输入的时间转为业务需要时间, 规则如下:
// 1. 1分钟内发布的: 刚刚
// 2. 1小时内发布的: X分钟前
// 3. 超过1小时, 仍在当天: xx:xx
// 4. 跨天,但少于24小时: 昨天 xx:xx
// 5. 跨天, 超过24小时: xxxx-xx-xx xx:xx
func FormatBusinessDate(date string) (finalStr string) {
timeObj := Datetime2TimeObj(date, DatetimeFmt)
inDate := timeObj.Format(DateFmt) // 输入的日期
inTimestamp := timeObj.Unix() // 输入的时间戳
curTimeObj := time.Now()
curDate := curTimeObj.Format(DateFmt)
curTimestamp := curTimeObj.Unix()
var (
minute int64 = 60 // 1 分钟
hour = 60 * minute
day = 24 * hour
)
diffVal := curTimestamp - inTimestamp
if diffVal < minute {
finalStr = "刚刚"
} else if diffVal < hour {
finalStr = ToString(diffVal/minute) + "分钟前"
} else if diffVal > hour && inDate == curDate {
// 2021-08-10 10:37:35 => 10:37
finalStr = date[11:16]
} else if inTimestamp > curTimestamp-day {
finalStr = "昨天 " + date[11:16]
} else {
finalStr = date[:16]
}
return
}
// GetWeekInfoForTime 根据输入的 time 来获取本周的日期和星期几, 如果没有输入默认按当前时间处理
func GetWeekInfoForTime(dateFormat string, t ...time.Time) *weekInfo {
weeks := []string{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}
if dateFormat == "" {
dateFormat = DateFmt
}
curTimeObj := time.Now()
if len(t) > 0 {
curTimeObj = t[0]
}
curWeekDayInt := int(curTimeObj.Weekday())
if curWeekDayInt == 0 {
curWeekDayInt = 7
}
startTimeObj := curTimeObj.AddDate(0, 0, 1-curWeekDayInt)
endTimeObj := startTimeObj.AddDate(0, 0, 6)
startDate := startTimeObj.Format(dateFormat)
endDate := endTimeObj.Format(dateFormat)
date2weekMap := make(map[string]string, 7)
dates := make([]string, 7)
for i := 0; i <= 6; i++ {
tmpDate := startTimeObj.AddDate(0, 0, i).Format(dateFormat)
dates[i] = tmpDate
date2weekMap[tmpDate] = weeks[i]
}
return &weekInfo{
StartTimeObj: startTimeObj,
EndTimeObj: endTimeObj,
StartDate: startDate,
EndDate: endDate,
Dates: dates,
Date2WeekMap: date2weekMap,
}
}
// DatetimeIsExpire 判断输入时间是否过期
func DatetimeIsExpire(date string, expire ...time.Duration) bool {
timeObj, err := time.ParseInLocation(DatetimeFmt, date, time.Local)
if err != nil { // 按过期处理
internal.Error("time.ParseInLocation is failed, err: ", err)
return true
}
if len(expire) > 0 {
return timeObj.Add(expire[0]).Before(time.Now())
}
return timeObj.Before(time.Now())
}
// SubDate 获取两个时间的差值
func SubDate(date, sub string, format ...string) time.Duration {
defaultFormat := DateFmt
if len(format) > 0 {
defaultFormat = format[0]
}
dateObj, err := time.ParseInLocation(defaultFormat, date, time.Local)
if err != nil {
internal.Error("time.ParseInLocation is failed, err: ", err)
return 0
}
subObj, err := time.ParseInLocation(defaultFormat, sub, time.Local)
if err != nil {
internal.Error("time.ParseInLocation is failed, err: ", err)
return 0
}
return dateObj.Sub(subObj)
}
// AddDate 增加时间
func AddDate(date string, add time.Duration, format ...string) time.Time {
defaultFormat := DateFmt
if len(format) > 0 {
defaultFormat = format[0]
}
return Datetime2TimeObj(date, defaultFormat).Add(add)
}
// AddDateForInt 增加时间
func AddDateForInt(date string, years, months, days int, format ...string) time.Time {
defaultFormat := DateFmt
if len(format) > 0 {
defaultFormat = format[0]
}
return Datetime2TimeObj(date, defaultFormat).AddDate(years, months, days)
}
// Datetime2Timestamp 将时间字符串转为时间戳
func Datetime2Timestamp(date string, format ...string) int64 {
defaultFormat := DatetimeFmt
if len(format) > 0 {
defaultFormat = format[0]
}
return Datetime2TimeObj(date, defaultFormat).Unix()
}
// Timestamp2Datetime 将时间戳转为时间字符串
func Timestamp2Datetime(timestamp int64, format ...string) string {
defaultFormat := DatetimeFmt
if len(format) > 0 {
defaultFormat = format[0]
}
return time.Unix(timestamp, 0).Format(defaultFormat)
}
// GetAgeForBirthday 根据出生日期获取年龄
func GetAgeForBirthday(birthday string, format ...string) (age int) {
if birthday == "" || len(birthday) < 4 {
return
}
defaultFormat := DateFmt
if len(format) > 0 && format[0] != "" {
defaultFormat = format[0]
}
// 计算 age
subStr := time.Since(Datetime2TimeObj(birthday, defaultFormat)).String()
hourIndex := strings.Index(subStr, "h")
if hourIndex <= 0 {
return
}
hourInt, _ := strconv.Atoi(subStr[:hourIndex])
return hourInt / 24 / 365
}
// SubNow2Year 目标年与现在的差
func SubNow2Year(year string) string {
yearInt, _ := strconv.Atoi(year)
nowInt := time.Now().Year()
sub := nowInt - yearInt
if sub <= 0 {
sub = 0
}
return ToString(sub)
}
// GetCurMonthDur 获取指定月的开始和结束时间
func GetTargeMonthDur(target time.Time) (startDatetime, endDatetime string) {
if target.Day() == 1 { // 说明为 1 号, 可以直接处理
startDatetime = target.Format(DateFmt) + StartTimeSuffix
endDatetime = target.AddDate(0, 1, 0).AddDate(0, 0, -1).Format(DateFmt) + EndTimeSuffix
return
}
startDatetime = target.Format(DateFmt)[:7] + "-01" + StartTimeSuffix
endDatetime = AddDateForInt(startDatetime, 0, 1, 0, DatetimeFmt).AddDate(0, 0, -1).Format(DateFmt) + EndTimeSuffix
return
}
// GetAddDateDur 获取指定时间的当天开始时间和结束时间
func GetTargetDateDur(target time.Time) (startDatetime, endDatetime string) {
fmtDate := target.Format(DateFmt)
startDatetime = fmtDate + StartTimeSuffix
endDatetime = fmtDate + EndTimeSuffix
return
}
// Datetime2TimeObj
func Datetime2TimeObj(target string, format ...string) time.Time {
defaultFormat := DatetimeFmt
if len(format) > 0 {
defaultFormat = format[0]
}
timeObj, err := time.ParseInLocation(defaultFormat, target, time.Local)
if err != nil {
internal.Error("time.ParseInLocation is failed, err: ", err)
return time.Time{}
}
return timeObj
}
// DatetimeBetween 判断目标时间是否在开始时间和结束时间之间
func DatetimeBetween(target, startDatetime, endDatetime string) bool {
targetObj := Datetime2TimeObj(target)
startObj := Datetime2TimeObj(startDatetime)
endObj := Datetime2TimeObj(endDatetime)
if startObj.Equal(targetObj) || endObj.Equal(targetObj) {
return true
}
return startObj.Before(targetObj) && endObj.After(targetObj)
}
// GetDateBetween 获取开始时间和结束时间中的日期
// args[0] 为操作类型, 默认为 GetDateBetweenForDate
// args[1] 为了防止死循环设置的最大循环次数, 默认 365(1年)
func GetDateBetween(startDate, endDate string, args ...int32) []string {
// internal.Infof("GetDateBetween s: %s, e: %s, args: %v", startDate, endDate, args)
if len(startDate) != 10 {
return nil
}
if len(startDate) != len(endDate) {
return nil
}
startDateObj := Datetime2TimeObj(startDate, DateFmt)
endDateObj := Datetime2TimeObj(endDate, DateFmt)
if startDateObj.After(endDateObj) {
return nil
}
if startDate == endDate {
return []string{startDate}
}
defaultType := GetDateBetweenForDate
addParams := []int{0, 0, 1}
stop := 365
if len(args) > 0 {
defaultType = args[0]
if len(args) == 2 {
stop = int(args[1])
}
}
if !InInt32Array(defaultType, GetDateBetweenForDate, GetDateBetweenForMonth, GetDateBetweenForYear) {
return nil
}
if defaultType == GetDateBetweenForMonth {
addParams = []int{0, 1, 0}
startDate = startDate[:7]
endDate = endDate[:7]
if startDate == endDate {
return []string{startDate}
}
}
if defaultType == GetDateBetweenForYear {
addParams = []int{1, 0, 0}
startDate = startDate[:4]
endDate = endDate[:4]
if startDate == endDate {
return []string{startDate}
}
}
res := []string{startDate}
for i := 0; i < stop; i++ {
startDateObj = startDateObj.AddDate(addParams[0], addParams[1], addParams[2])
tmpDateFmt := startDateObj.Format(DateFmt)
if defaultType == GetDateBetweenForMonth {
tmpDateFmt = tmpDateFmt[:7]
}
if defaultType == GetDateBetweenForYear {
tmpDateFmt = tmpDateFmt[:4]
}
res = append(res, tmpDateFmt)
if tmpDateFmt == endDate {
break
}
}
return res
}
// Second2Hour 秒转分
func Second2Hour(s int) (hour, min, sec int) {
if s <= 0 {
return
}
hour = s / 3600
min = s / 60 % 60
sec = s % 60
return
}
// GetTimeFmt 获取时间格式化
// splits 为分隔符
// splits[0] 为 [年月日] 的分割符, 默认为 "-"
// splits[1] 为 [年月日] 和 [时分秒] 的分割符, 默认为 " "
// splits[2] 为 [时分秒] 的分割符, 默认为 ":"
func GetTimeFmt(fmtType int8, splits ...string) string {
defaultDateSplit := "-"
defaultDateTimeSplit := " "
defaultTimeSplit := ":"
l := len(splits)
switch l {
case 1:
defaultDateSplit = splits[0]
case 2:
defaultDateSplit = splits[0]
defaultDateTimeSplit = splits[1]
case 3:
defaultDateSplit = splits[0]
defaultDateTimeSplit = splits[1]
defaultTimeSplit = splits[2]
}
joinFn := func(old, split, join string) string {
if old == "" {
return join
}
if join == "" {
return old
}
return old + split + join
}
// 年月日
prefix := ""
if fmtType&YearFmt > 0 {
prefix = joinFn(prefix, defaultDateSplit, "2006")
}
if fmtType&MonthFmt > 0 {
prefix = joinFn(prefix, defaultDateSplit, "01")
}
if fmtType&DayFmt > 0 {
prefix = joinFn(prefix, defaultDateSplit, "02")
}
// 时分秒
suffix := ""
if fmtType&HourFmt > 0 {
suffix = joinFn(suffix, defaultTimeSplit, "15")
}
if fmtType&MinFmt > 0 {
suffix = joinFn(suffix, defaultTimeSplit, "04")
}
if fmtType&SecFmt > 0 {
suffix = joinFn(suffix, defaultTimeSplit, "05")
}
if fmtType&MilliFmt > 0 {
suffix = joinFn(suffix, ".", "000")
}
return joinFn(prefix, defaultDateTimeSplit, suffix)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/xuesongtao/gotool.git
git@gitee.com:xuesongtao/gotool.git
xuesongtao
gotool
gotool
v1.2.18

搜索帮助