苏州瑞玛APS项目web后台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

541 lines
12 KiB

package utils
import (
"errors"
"fmt"
"log"
"math"
"strconv"
"strings"
"time"
)
var TimezoneLocation *time.Location
type ITimer struct {
*time.Timer
name string
exited bool
isRunning bool
d time.Duration
fn func()
}
func itimerDefaultFunc() {}
func NewTimer(d time.Duration) *ITimer {
tm := &ITimer{
Timer: time.NewTimer(d),
exited: false,
isRunning: true,
d: d,
fn: itimerDefaultFunc,
}
tm.Pause()
return tm
}
func (tm *ITimer) SetName(nm string) {
tm.name = nm
}
func (tm *ITimer) Name() string {
return tm.name
}
func (tm *ITimer) Exit() bool {
tm.exited = tm.Timer.Reset(0)
return tm.exited
}
func (tm *ITimer) IsExit() bool {
return tm.exited
}
func (tm *ITimer) reset() bool {
if tm.exited {
return false
}
tm.isRunning = true
return tm.Timer.Reset(tm.d)
}
func (tm *ITimer) Pause() bool {
tm.isRunning = false
return tm.Timer.Reset(time.Duration(math.MaxInt64))
}
func (tm *ITimer) Continue() bool {
tm.isRunning = true
return tm.reset()
}
func (tm *ITimer) IsRunning() bool {
if tm.exited {
return false
}
return tm.isRunning
}
func (tm *ITimer) SetFunc(fn func()) {
tm.fn = fn
}
func (tm *ITimer) NowExecFunc() {
if tm.fn != nil {
go tm.fn()
}
tm.reset()
}
func (tm *ITimer) Run() {
for {
select {
case <-tm.C:
if tm.IsExit() {
tm.isRunning = false
return
}
tm.reset()
if tm.fn != nil {
go tm.fn()
}
}
}
}
//format time like java, such as: yyyy-MM-dd HH:mm:ss
func TimeFormat(t time.Time, format string) string {
//year
if strings.ContainsAny(format, "y") {
year := strconv.Itoa(t.Year())
if strings.Count(format, "yy") == 1 && strings.Count(format, "y") == 2 {
format = strings.Replace(format, "yy", year[2:], 1)
} else if strings.Count(format, "yyyy") == 1 && strings.Count(format, "y") == 4 {
format = strings.Replace(format, "yyyy", year, 1)
} else {
log.Fatalln("format year error! please 'yyyy' or 'yy'")
}
}
//month
if strings.ContainsAny(format, "M") {
var month string
if int(t.Month()) < 10 {
month = "0" + strconv.Itoa(int(t.Month()))
} else {
month = strconv.Itoa(int(t.Month()))
}
if strings.Count(format, "MM") == 1 && strings.Count(format, "M") == 2 {
format = strings.Replace(format, "MM", month, 1)
} else {
log.Fatalln("format month error! please 'MM'")
}
}
//day
if strings.ContainsAny(format, "d") {
var day string
if t.Day() < 10 {
day = "0" + strconv.Itoa(t.Day())
} else {
day = strconv.Itoa(t.Day())
}
if strings.Count(format, "dd") == 1 && strings.Count(format, "d") == 2 {
format = strings.Replace(format, "dd", day, 1)
} else {
log.Fatalln("format day error! please 'dd'")
}
}
//hour
if strings.ContainsAny(format, "H") {
var hour string
if t.Hour() < 10 {
hour = "0" + strconv.Itoa(t.Hour())
} else {
hour = strconv.Itoa(t.Hour())
}
if strings.Count(format, "HH") == 1 && strings.Count(format, "H") == 2 {
format = strings.Replace(format, "HH", hour, 1)
} else {
log.Fatalln("format hour error! please 'HH'")
}
}
//minute
if strings.ContainsAny(format, "m") {
var minute string
if t.Minute() < 10 {
minute = "0" + strconv.Itoa(t.Minute())
} else {
minute = strconv.Itoa(t.Minute())
}
if strings.Count(format, "mm") == 1 && strings.Count(format, "m") == 2 {
format = strings.Replace(format, "mm", minute, 1)
} else {
log.Fatalln("format minute error! please 'mm'")
}
}
//second
if strings.ContainsAny(format, "s") {
var second string
if t.Second() < 10 {
second = "0" + strconv.Itoa(t.Second())
} else {
second = strconv.Itoa(t.Second())
}
if strings.Count(format, "ss") == 1 && strings.Count(format, "s") == 2 {
format = strings.Replace(format, "ss", second, 1)
} else {
log.Fatalln("format second error! please 'ss'")
}
}
return format
}
//2007-11-23 10:02:14/20071123100214
func TimeParse(str string) (time.Time, error) {
ll := len(str)
if ll == 19 {
loc, _ := time.LoadLocation("Local")
return time.ParseInLocation("2006-01-02 15:04:05", str, loc)
} else if ll == 14 {
loc, _ := time.LoadLocation("Local")
return time.ParseInLocation("20060102150405", str, loc)
}
return time.Time{}, errors.New("str len is error")
}
//17:02:03/170203
func TimeParseHHmmss(str string) (time.Time, error) {
ll := len(str)
if ll != 8 && ll != 6 {
return time.Time{}, errors.New("input str is error")
}
if ll == 8 {
return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str))
}
return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str))
}
//17:02/1702
func TimeParseHHmm(str string) (time.Time, error) {
ll := len(str)
if ll != 5 && ll != 4 {
return time.Time{}, errors.New("input str is error")
}
if ll == 5 {
return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str+":00"))
}
return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str+"00"))
}
//2007-05-69/20070569
func TimeParseyyyyMMdd(str string) (time.Time, error) {
ll := len(str)
if ll != 10 && ll != 8 {
return time.Time{}, errors.New("input str is error")
}
if ll == 10 {
return TimeParse(TimeFormat(time.Now(), str+" 00:00:00"))
}
return TimeParse(TimeFormat(time.Now(), str+"000000"))
}
//计算时间差返回秒级 样例: T1 = 16:00 t2 = 08:00
func Timelen(t1 string, t2 string) (int, error) {
var time1 int64
var time2 int64
len1 := len(t1)
if len1 != 4 && len1 != 5 {
return 0, errors.New("input str is error")
}
len2 := len(t2)
if len2 != 4 && len2 != 5 {
return 0, errors.New("input str is error")
}
tem1, _ := TimeParseHHmm(t1)
time1 = tem1.Unix()
tem2, _ := TimeParseHHmm(t2)
time2 = tem2.Unix()
timelen := time1 - time2
return int(timelen), nil
}
//获取某一天的0点时间
func GetZeroTime(d time.Time) time.Time {
now := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
return now
}
//返回格式:例如2016-05-01 00:00:00的时间戳到2016-06-01 00:00:00的时间戳
func TimeReturnMonth(now time.Time) (firstMonth string, lastMonth string) {
currentYear, currentMonth, _ := now.Date()
currentLocation := now.Location()
firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
lastOfMonth := firstOfMonth.AddDate(0, 1, 0).Add(time.Second * -1)
return TimeFormat(firstOfMonth, "yyyyMMdd"), TimeFormat(lastOfMonth, "yyyyMMdd")
}
// 获取两个时间点之间的天数
func GetCrossDays(t1, t2 time.Time) (days int) {
var (
y1, d1, y2, d2 int
m1, m2 time.Month
date1, date2 time.Time
)
days = 0
if t1.Unix() >= t2.Unix() {
return
}
y1, m1, d1 = t1.Date()
y2, m2, d2 = t2.Date()
date1 = time.Date(y1, m1, d1, 0, 0, 0, 0, time.UTC)
date2 = time.Date(y2, m2, d2, 0, 0, 0, 0, time.UTC)
days = int(date2.Sub(date1).Hours() / 24)
return
}
// 获取时间点的日期,以年月日字符类型数据返回
func GetYMDString(t time.Time) (ymd string) {
var (
y1, d1 int
m1 time.Month
)
y1, m1, d1 = t.Date()
ymd = fmt.Sprintf("%04d", y1) + fmt.Sprintf("%02d", int(m1)) + fmt.Sprintf("%02d", d1)
return
}
func ParseWeekIndex(date time.Time) int {
dateStr := date.Format("2006-01-02")
dateStr = dateStr[:8] + "01"
firstDay, _ := time.ParseInLocation("2006-01-02", dateStr, TimezoneLocation)
firstWeekDay := firstDay.Weekday()
weekDay := date.Weekday()
for i := 1; i < 6; i++ {
date = date.AddDate(0, 0, -7)
if date.Before(firstDay) {
if weekDay >= firstWeekDay {
return i
}
return i + 1
}
}
return 0
}
// 获取线段上两个时间点之间的Duration
func GetDuration(startTime, endTime time.Time, EffFactor float64) (duration time.Duration) {
var seconds float64
if endTime.Unix() <= startTime.Unix() {
duration = 0
return
}
if EffFactor <= 0 {
EffFactor = 1
}
seconds = endTime.Sub(startTime).Seconds() * EffFactor
duration = time.Duration(seconds) * time.Second
return
}
func ZellerFunction2Week(year, month, day uint16) int {
var y, m, c uint16
if month >= 3 {
m = month
y = year % 100
c = year / 100
} else {
m = month + 12
y = (year - 1) % 100
c = (year - 1) / 100
}
week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
if week < 0 {
week = 7 - (-week)%7
} else {
week = week % 7
}
which_week := int(week)
return which_week
}
//判断时间是当年的第几周
func WeekByDate(t time.Time) (int, int, time.Month) {
var yearFirstDay time.Time
var yearDay int
//计算当前时间是周几
year, month, day := t.Date()
firstWeek := ZellerFunction2Week(uint16(year), uint16(month), uint16(day))
dayLen := 7 - firstWeek
//计算周日的时间,防止跨年
startDate := t.AddDate(0, 0, dayLen)
nextyear, nextmonth, _ := startDate.Date()
//判断是否跨年
if nextyear > year {
year = nextyear
month = nextmonth
yearDay = startDate.YearDay()
yearFirstDay = startDate.AddDate(0, 0, -yearDay+1)
} else {
yearDay = t.YearDay()
yearFirstDay = t.AddDate(0, 0, -yearDay+1)
}
firstDayInWeek := int(yearFirstDay.Weekday())
//今年第一周有几天
firstWeekDays := 1
if firstDayInWeek != 0 {
firstWeekDays = 7 - firstDayInWeek + 1
}
var week int
if yearDay <= firstWeekDays {
week = 1
} else {
week = (yearDay-firstWeekDays)/7 + 2
}
return week, year, month
}
//判断时间是当年的第几周
func WeekByDateStr(t time.Time) string {
yearDay := t.YearDay()
yearFirstDay := t.AddDate(0, 0, -yearDay+1)
firstDayInWeek := int(yearFirstDay.Weekday())
//今年第一周有几天
firstWeekDays := 1
if firstDayInWeek != 0 {
firstWeekDays = 7 - firstDayInWeek + 1
}
var week int
if yearDay <= firstWeekDays {
week = 1
} else {
week = (yearDay-firstWeekDays)/7 + 2
}
return fmt.Sprintf("%d.%d", t.Year(), week)
}
type WeekDate struct {
WeekTh string
StartTime time.Time
EndTime time.Time
}
// 将开始时间和结束时间分割为周为单位
func GroupByWeekDate(startTime, endTime time.Time) []WeekDate {
weekDate := make([]WeekDate, 0)
diffDuration := endTime.Sub(startTime)
days := int(math.Ceil(float64(diffDuration/(time.Hour*24)))) + 1
currentWeekDate := WeekDate{}
currentWeekDate.WeekTh = WeekByDateStr(endTime)
currentWeekDate.EndTime = endTime
currentWeekDay := int(endTime.Weekday())
if currentWeekDay == 0 {
currentWeekDay = 7
}
currentWeekDate.StartTime = endTime.AddDate(0, 0, -currentWeekDay+1)
nextWeekEndTime := currentWeekDate.StartTime
weekDate = append(weekDate, currentWeekDate)
for i := 0; i < (days-currentWeekDay)/7; i++ {
weekData := WeekDate{}
weekData.EndTime = nextWeekEndTime
weekData.StartTime = nextWeekEndTime.AddDate(0, 0, -7)
weekData.WeekTh = WeekByDateStr(weekData.StartTime)
nextWeekEndTime = weekData.StartTime
weekDate = append(weekDate, weekData)
}
if lastDays := (days - currentWeekDay) % 7; lastDays > 0 {
lastData := WeekDate{}
lastData.EndTime = nextWeekEndTime
lastData.StartTime = nextWeekEndTime.AddDate(0, 0, -lastDays)
lastData.WeekTh = WeekByDateStr(lastData.StartTime)
weekDate = append(weekDate, lastData)
}
return weekDate
}
//周一0点
func WeekDayMondayZeroTs(now time.Time) time.Time {
offset := int(time.Monday - now.Weekday())
if offset > 0 {
offset = -6
}
weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
return weekStart
}
func WeekDaySaturdayZeroTs(now time.Time) time.Time {
offset := int(time.Monday - now.Weekday())
if offset > 0 {
offset = -6
}
offset += 5
weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
return weekStart
}
func WeekDaySundayZeroTs(now time.Time) time.Time {
offset := int(time.Monday - now.Weekday())
if offset > 0 {
offset = -6
}
offset += 6
weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
return weekStart
}