416 lines
12 KiB
Go
416 lines
12 KiB
Go
|
package timeutil
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"strconv"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
func New() *TimeUtil {
|
|||
|
return &TimeUtil{}
|
|||
|
}
|
|||
|
|
|||
|
// TimeUtil 是时间操作工具类
|
|||
|
type TimeUtil struct{}
|
|||
|
|
|||
|
// GetFormattedDate 获取格式化的日期字符串
|
|||
|
func (tu *TimeUtil) GetFormattedDate(t time.Time) string {
|
|||
|
return t.Format("2006-01-02")
|
|||
|
}
|
|||
|
|
|||
|
// GetFormattedTime 获取格式化的时间字符串
|
|||
|
func (tu *TimeUtil) GetFormattedTime(t time.Time) string {
|
|||
|
return t.Format("15:04:05")
|
|||
|
}
|
|||
|
|
|||
|
// GetFormattedDateTime 获取格式化的日期时间字符串
|
|||
|
func (tu *TimeUtil) GetFormattedDateTime(t time.Time) string {
|
|||
|
return t.Format("2006-01-02 15:04:05")
|
|||
|
}
|
|||
|
|
|||
|
// GetWeekday 获取星期几
|
|||
|
func (tu *TimeUtil) GetWeekday(t time.Time) string {
|
|||
|
return t.Weekday().String()
|
|||
|
}
|
|||
|
|
|||
|
// IsLeapYear 判断是否为闰年
|
|||
|
func (tu *TimeUtil) IsLeapYear(year int) bool {
|
|||
|
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
|
|||
|
}
|
|||
|
|
|||
|
// ParseDateFromString 将日期字符串解析为时间对象
|
|||
|
func (tu *TimeUtil) ParseDateFromString(dateString string) (time.Time, error) {
|
|||
|
layout := "2006-01-02"
|
|||
|
t, err := time.Parse(layout, dateString)
|
|||
|
if err != nil {
|
|||
|
return time.Time{}, err
|
|||
|
}
|
|||
|
return t, nil
|
|||
|
}
|
|||
|
|
|||
|
// ParseTimeFromString 将时间字符串解析为时间对象
|
|||
|
func (tu *TimeUtil) ParseTimeFromString(timeString string) (time.Time, error) {
|
|||
|
layout := "15:04:05"
|
|||
|
t, err := time.Parse(layout, timeString)
|
|||
|
if err != nil {
|
|||
|
return time.Time{}, err
|
|||
|
}
|
|||
|
return t, nil
|
|||
|
}
|
|||
|
|
|||
|
// ParseDateTimeFromString 将日期时间字符串解析为时间对象
|
|||
|
func (tu *TimeUtil) ParseDateTimeFromString(dateTimeString string) (time.Time, error) {
|
|||
|
layout := "2006-01-02 15:04:05"
|
|||
|
t, err := time.Parse(layout, dateTimeString)
|
|||
|
if err != nil {
|
|||
|
return time.Time{}, err
|
|||
|
}
|
|||
|
return t, nil
|
|||
|
}
|
|||
|
|
|||
|
// NowTime 获取当前时间 format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
|
|||
|
func (tu *TimeUtil) NowTime(format string) (timeDate time.Time) {
|
|||
|
// 获取当前时间
|
|||
|
currentTime := time.Now()
|
|||
|
// 使用时间格式化函数,将时间转换为指定格式的字符串
|
|||
|
formattedTime := currentTime.Format(rule(format))
|
|||
|
// 输出格式化后的时间字符串
|
|||
|
fmt.Println(formattedTime)
|
|||
|
// 如果你需要将时间转换为 time.Time 类型,直接使用 currentTime 即可
|
|||
|
// 这里的 currentTime 就是 time.Time 类型的对象
|
|||
|
fmt.Println(currentTime)
|
|||
|
return currentTime
|
|||
|
}
|
|||
|
|
|||
|
// FormatTimeString 将时间字符串转换为指定格式的日期时间字符串
|
|||
|
/**
|
|||
|
inputTime 表示输入的时间字符串 字符格式为:2006-01-02 15:04:05
|
|||
|
format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
|
|||
|
*/
|
|||
|
func (tu *TimeUtil) FormatTimeString(inputTime, format string) (string, error) {
|
|||
|
format = rule(format)
|
|||
|
layout := "2006-01-02 15:04:05"
|
|||
|
t, err := time.Parse(layout, inputTime)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
formattedTime := t.Format(format)
|
|||
|
return formattedTime, nil
|
|||
|
}
|
|||
|
|
|||
|
// FormatTimeStringZ 将时间字符串转换为指定格式的日期时间字符串
|
|||
|
/**
|
|||
|
inputTime 表示输入的时间字符串 字符格式为:2023-07-29T15:30:00Z
|
|||
|
format 表示要转换的日期时间格式 1、YYYY-MM-DD hh:mm:ss 2、YYYY-MM-DD 3、hh:mm:ss
|
|||
|
*/
|
|||
|
func (tu *TimeUtil) FormatTimeStringZ(inputTime, format string) (string, error) {
|
|||
|
format = rule(format)
|
|||
|
t, err := time.Parse(time.RFC3339, inputTime)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
formattedTime := t.Format(format)
|
|||
|
return formattedTime, nil
|
|||
|
}
|
|||
|
|
|||
|
// CalculateAge 计算年龄 传递参数格式为20060406
|
|||
|
func (tu *TimeUtil) CalculateAge(timeStr string) string {
|
|||
|
if len(timeStr) > 0 {
|
|||
|
// 定义时间字符串和时间格式
|
|||
|
timeFormat := "2006-01-02"
|
|||
|
|
|||
|
// 将时间字符串解析为时间对象
|
|||
|
birthDate, err := time.Parse(timeFormat, timeStr)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("无法解析时间字符串:", err)
|
|||
|
}
|
|||
|
|
|||
|
//当前时间
|
|||
|
currentDate := time.Now()
|
|||
|
|
|||
|
// 计算年份差值
|
|||
|
years := currentDate.Year() - birthDate.Year()
|
|||
|
|
|||
|
// 检查月份和日期,如果当前日期还没过生日,则年龄减一
|
|||
|
if currentDate.Month() < birthDate.Month() ||
|
|||
|
(currentDate.Month() == birthDate.Month() && currentDate.Day() < birthDate.Day()) {
|
|||
|
years -= 1
|
|||
|
}
|
|||
|
return strconv.Itoa(years)
|
|||
|
}
|
|||
|
return ""
|
|||
|
}
|
|||
|
|
|||
|
func StringDateComparison(comparisonTime, scopeA, scopeB string) (flag bool) {
|
|||
|
// 将日期字符串解析为时间对象
|
|||
|
startTime, err := time.Parse("2006-01-02", scopeA)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("解析开始日期时出错:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
endTime, err := time.Parse("2006-01-02", scopeB)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("解析结束日期时出错:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
// 要检查的日期
|
|||
|
checkTime, err := time.Parse("2006-01-02", comparisonTime)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("解析要检查的日期时出错:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
// 检查a是否在start和end之间
|
|||
|
if checkTime.After(startTime) && checkTime.Before(endTime) || checkTime.Equal(startTime) || checkTime.Equal(endTime) {
|
|||
|
return true
|
|||
|
} else {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TimeWithin 判断一个时间字符串是否在on和off之间,注意on和off规则为时分【09:00】 返回值1为在范围内 返回值2为不在范围内
|
|||
|
/**
|
|||
|
strTime 需要判断的时间
|
|||
|
on 范围起始时间
|
|||
|
off 范围结束时间
|
|||
|
*/
|
|||
|
func (tu *TimeUtil) TimeWithin(strTime string, on string, off string, clockStatus string) string {
|
|||
|
format := "2006-01-02 15:04:05"
|
|||
|
|
|||
|
now := time.Now()
|
|||
|
year, month, day := now.Date()
|
|||
|
|
|||
|
// 构建完整的日期时间字符串
|
|||
|
onTimeStr := ""
|
|||
|
if clockStatus == "1" {
|
|||
|
onTimeStr = fmt.Sprintf("%d-%02d-%02d %s:00", year, month, day, on)
|
|||
|
} else {
|
|||
|
onTimeStr = fmt.Sprintf("%d-%02d-%02d %s:00", year, month, day, off)
|
|||
|
}
|
|||
|
|
|||
|
// 解析时间字符串为时间对象
|
|||
|
onTime, err := time.Parse(format, onTimeStr)
|
|||
|
if err != nil {
|
|||
|
// 错误处理
|
|||
|
}
|
|||
|
|
|||
|
strDateTime, err := time.Parse(format, strTime)
|
|||
|
if err != nil {
|
|||
|
// 错误处理
|
|||
|
}
|
|||
|
|
|||
|
// 判断strTime与onTime、offTime的关系
|
|||
|
/**
|
|||
|
定义了
|
|||
|
var on = “09:00”
|
|||
|
var off = “18:00”
|
|||
|
判断strTime“2023-06-07 17:44:49”
|
|||
|
on和off自动填补上年月日(比如说on为09:00,自动补充为2023-06-07 09:00:00然后与2023-06-07 17:44:49比较)
|
|||
|
strTime小于等于on大于等于off返回1,
|
|||
|
strTime大于on返回2,
|
|||
|
strTime小于off为3
|
|||
|
*/
|
|||
|
|
|||
|
if clockStatus == "1" { //上班
|
|||
|
if strDateTime.Before(onTime) || strDateTime.Equal(onTime) {
|
|||
|
return "1" //表示正常
|
|||
|
} else {
|
|||
|
if clockStatus == "1" {
|
|||
|
return "2" //表述迟到
|
|||
|
} else {
|
|||
|
//表示offTime小于等于strDateTime
|
|||
|
return "1" //表示正常
|
|||
|
}
|
|||
|
}
|
|||
|
} else { //下班
|
|||
|
if strDateTime.After(onTime) || strDateTime.Equal(onTime) {
|
|||
|
return "1" //表示正常
|
|||
|
} else {
|
|||
|
if clockStatus == "2" {
|
|||
|
return "3" //表述早退
|
|||
|
} else {
|
|||
|
//表示offTime小于等于strDateTime
|
|||
|
return "1" //表示正常
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// TimeCycle 将字符串20060102转成2006-01-02
|
|||
|
func (tu *TimeUtil) TimeCycle(dateStr string) (str string, err error) {
|
|||
|
date, err := time.Parse("20060102", dateStr)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("解析时间失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
formattedDate := date.Format("2006-01-02")
|
|||
|
return formattedDate, err
|
|||
|
}
|
|||
|
|
|||
|
// rule 时间规则
|
|||
|
func rule(format string) (str string) {
|
|||
|
if format == "1" {
|
|||
|
format = "2006-01-02 15:04:05"
|
|||
|
} else if format == "2" {
|
|||
|
format = "2006-01-02"
|
|||
|
} else if format == "3" {
|
|||
|
format = "15:04:05"
|
|||
|
}
|
|||
|
return format
|
|||
|
}
|
|||
|
|
|||
|
// GetDaysDifference 根据字符串时间2023-08-09 减去当前时间 得到 差异天数
|
|||
|
func GetDaysDifference(strDate string) int {
|
|||
|
layout := "2006-01-02" // 指定日期字符串的格式
|
|||
|
t, err := time.Parse(layout, strDate)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("日期解析错误:", err)
|
|||
|
return -1
|
|||
|
}
|
|||
|
now := time.Now()
|
|||
|
duration := now.Sub(t)
|
|||
|
days := int(duration.Hours() / 24)
|
|||
|
|
|||
|
return days
|
|||
|
}
|
|||
|
|
|||
|
// RangeTime 根据时间段获取到时间段内的所有时间 2023-10-01 17:26:56 ~ 2023-10-07 17:26:56里的所有时间(年-月-日)
|
|||
|
func RangeTime(startDateStr, endDateStr string) (qp []string) {
|
|||
|
if startDateStr == "" || endDateStr == "" {
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 解析起始日期和结束日期
|
|||
|
startDate, err := time.Parse("2006-01", startDateStr)
|
|||
|
if err != nil {
|
|||
|
fmt.Printf("无法解析起始日期:%s\n", err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
endDate, err := time.Parse("2006-01", endDateStr)
|
|||
|
if err != nil {
|
|||
|
fmt.Printf("无法解析结束日期:%s\n", err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 生成日期范围并输出
|
|||
|
currentDate := startDate
|
|||
|
for !currentDate.After(endDate) {
|
|||
|
format := currentDate.Format("2006-01")
|
|||
|
qp = append(qp, format)
|
|||
|
currentDate = currentDate.AddDate(0, 1, 0)
|
|||
|
}
|
|||
|
|
|||
|
return qp
|
|||
|
}
|
|||
|
|
|||
|
// TimeStr 根据时间字符串 09:00 转成 2023-10-17 09:00:00 然后 再减去10分钟 在转成 time.Duration
|
|||
|
func TimeStr(timeString string) (dn time.Duration, err error) {
|
|||
|
currentTime := time.Now()
|
|||
|
newTimeString := fmt.Sprintf("%s %s", currentTime.Format("2006-01-02"), timeString)
|
|||
|
parsedTime, err := time.Parse("2006-01-02 15:04", newTimeString)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("时间解析错误:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
//duration := 10 * time.Minute
|
|||
|
//newTime := parsedTime.Add(-duration)
|
|||
|
|
|||
|
thisTime := currentTime.Format("2006-01-02 15:04:05")
|
|||
|
t, err := time.Parse("2006-01-02 15:04:05", thisTime)
|
|||
|
// 计算持续时间
|
|||
|
//dn = newTime.Sub(t)
|
|||
|
dn = parsedTime.Sub(t)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
func MillisecondTimestamp() int64 {
|
|||
|
// 获取当前时间
|
|||
|
currentTime := time.Now()
|
|||
|
// 将时间转换为毫秒时间戳
|
|||
|
milliseconds := currentTime.UnixNano() / int64(time.Millisecond)
|
|||
|
return milliseconds
|
|||
|
}
|
|||
|
|
|||
|
// TheBeginningAndTheEndOfTheMonth 获取当月的月初月末
|
|||
|
func TheBeginningAndTheEndOfTheMonth() (string, string) {
|
|||
|
currentTime := time.Now()
|
|||
|
firstDay := time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, currentTime.Location())
|
|||
|
lastDay := firstDay.AddDate(0, 1, 0).Add(-time.Second)
|
|||
|
statr := firstDay.Format("2006-01-02")
|
|||
|
end := lastDay.Format("2006-01-02")
|
|||
|
return statr, end
|
|||
|
}
|
|||
|
|
|||
|
// TheBeginningAndTheEndOfTheMonthAssign 获取指定月的月初月末
|
|||
|
func TheBeginningAndTheEndOfTheMonthAssign(selectedTime string) (string, string) {
|
|||
|
// 将指定时间解析为 time.Time 对象
|
|||
|
selectedTimeObj, err := time.Parse("2006-01", selectedTime)
|
|||
|
if err != nil {
|
|||
|
// 处理解析错误
|
|||
|
fmt.Println(err)
|
|||
|
return "", ""
|
|||
|
}
|
|||
|
// 获取当月的月初和月末
|
|||
|
firstDay := time.Date(selectedTimeObj.Year(), selectedTimeObj.Month(), 1, 0, 0, 0, 0, selectedTimeObj.Location())
|
|||
|
lastDay := firstDay.AddDate(0, 1, 0).Add(-time.Second)
|
|||
|
// 格式化开始日期和结束日期为字符串
|
|||
|
start := firstDay.Format("2006-01-02")
|
|||
|
end := lastDay.Format("2006-01-02")
|
|||
|
return start, end
|
|||
|
}
|
|||
|
|
|||
|
// CalculateTheDifferenceBetweenTheTwoTimePoints 计算两个字符串时间相差多少分钟
|
|||
|
func CalculateTheDifferenceBetweenTheTwoTimePoints(currentDateTime, targetTime string) float64 {
|
|||
|
// 计算时间差(以分钟为单位)
|
|||
|
diff := DateTimeSub(currentDateTime, targetTime).Minutes()
|
|||
|
return diff
|
|||
|
}
|
|||
|
|
|||
|
// CalculatesTheTimeDifferenceBetweenTwoStringsInHours 计算两个字符串时间相差多少小时
|
|||
|
func CalculatesTheTimeDifferenceBetweenTwoStringsInHours(currentDateTime, targetTime string) float64 {
|
|||
|
if currentDateTime == "00:00:00" || targetTime == "00:00:00" {
|
|||
|
return 0
|
|||
|
}
|
|||
|
// 计算时间差(以小时为单位)
|
|||
|
currentDateTime, _ = TimeToDateTimeFunc(currentDateTime)
|
|||
|
targetTime, _ = TimeToDateTimeFunc(targetTime)
|
|||
|
diff := DateTimeSub(currentDateTime, targetTime).Hours()
|
|||
|
return diff
|
|||
|
}
|
|||
|
|
|||
|
func DateTimeSub(currentDateTime, targetTime string) time.Duration {
|
|||
|
// 解析当前日期时间字符串
|
|||
|
t1, err := time.Parse("2006-01-02 15:04:05", currentDateTime)
|
|||
|
if err != nil {
|
|||
|
return 0
|
|||
|
}
|
|||
|
// 解析目标时间字符串
|
|||
|
t2, err := time.Parse("2006-01-02 15:04:05", targetTime)
|
|||
|
if err != nil {
|
|||
|
return 0
|
|||
|
}
|
|||
|
diff := t2.Sub(t1)
|
|||
|
return diff
|
|||
|
}
|
|||
|
|
|||
|
// TimeToDateTimeFunc 时间转成年月日时分秒格式
|
|||
|
func TimeToDateTimeFunc(timeStr string) (formattedTime string, err error) {
|
|||
|
// 当前日期
|
|||
|
currentDate := time.Now().Format("2006-01-02")
|
|||
|
|
|||
|
// 将时间字符串添加到当前日期的字符串中
|
|||
|
fullTimeStr := currentDate + " " + timeStr
|
|||
|
|
|||
|
// 解析完整的时间字符串
|
|||
|
parsedTime, err := time.Parse("2006-01-02 15:04:05", fullTimeStr)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("解析时间时出错:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 将解析后的时间格式化为“2006-01-02 15:04:05”
|
|||
|
formattedTime = parsedTime.Format("2006-01-02 15:04:05")
|
|||
|
return
|
|||
|
}
|