pengzz33 2022-07-25 17:31:04
【go】 获取时间范围数组,取并/交集合,支持跨天 方法:打点
type RecordTime struct {
StartTime int64 `json:"start_time"` // 开始时间
EndTime int64 `json:"end_time"` // 结束时间
}
func RecordData(list []RecordTime) map[string][]RecordTime {
newList := make([]RecordTime, 0, len(list))
// step:1 判断时间范围,相差天数
for _, r := range list {
if r.StartTime >= r.EndTime {
continue
}
timeStart := time.Unix(r.StartTime, 0)
timeEnd := time.Unix(r.EndTime, 0)
differNum := timeUtil.DaysBetween(timeEnd, timeStart)
if differNum > 0 {
newList = append(newList, RecordTime{
StartTime: r.StartTime,
EndTime: timeUtil.GetEndTime(timeStart).Unix(), // 获取某一天的23:59:59点时间
})
newList = append(newList, RecordTime{
StartTime: timeUtil.GetZeroTime(timeEnd).Unix(), // 获取某一天的0点时间
EndTime: r.EndTime,
})
} else {
newList = append(newList, RecordTime{
StartTime: r.StartTime,
EndTime: r.EndTime,
})
}
}
newMapList := make(map[string][]RecordTime)
// step:2 时间归类
for _, r := range newList {
timeStart := time.Unix(r.StartTime, 0)
timeString := timeStart.Format("2006-01-02")
if _, ok := newMapList[timeString]; !ok {
newMapList[timeString] = make([]RecordTime, 0)
}
newMapList[timeString] = append(newMapList[timeString], r)
}
// step:3 获取时间最大/最小的时间范围
newMapMaxTimeList := make(map[string]map[string]int64)
for _, newMapr := range newMapList {
for _, r := range newMapr {
timeStart := time.Unix(r.StartTime, 0)
timeString := timeStart.Format("2006-01-02")
if _, ok := newMapMaxTimeList[timeString]; !ok {
newMapMaxTimeList[timeString] = make(map[string]int64)
newMapMaxTimeList[timeString]["start_time"] = r.StartTime
newMapMaxTimeList[timeString]["end_time"] = r.EndTime
}
if r.StartTime < newMapMaxTimeList[timeString]["start_time"] && newMapMaxTimeList[timeString]["start_time"] > 0 {
newMapMaxTimeList[timeString]["start_time"] = r.StartTime
}
if r.EndTime > newMapMaxTimeList[timeString]["end_time"] {
newMapMaxTimeList[timeString]["end_time"] = r.EndTime
}
}
}
finalData := make(map[string][]RecordTime)
// step:3 构造一天的时间数组 时-分-秒
dateArr := make(map[string][]int64, 0)
for nk, n := range newMapMaxTimeList {
endTime := time.Unix(n["end_time"], 0)
dateArr[nk] = make([]int64, 0)
if len(newMapList[nk]) == 1 {
finalData[nk] = append(finalData[nk], RecordTime{
StartTime: newMapList[nk][0].StartTime,
EndTime: newMapList[nk][0].EndTime,
})
} else {
for _, r := range newMapList[nk] {
startTime := time.Unix(r.StartTime, 0)
calStartTime := timeUtil.TimeOfDate(int64(startTime.Year()), int64(startTime.Month()), int64(startTime.Day()), int64(startTime.Hour()), 0, 0, "Local") // 获取小时的time时间
isExit := false
count := (endTime.Hour() - startTime.Hour()) + 1
//获取时
for j := 0; j <= 3600*count; j++ {
num := (calStartTime.Unix() + int64(j))
if num == r.StartTime {
dateArr[nk] = append(dateArr[nk], num)
isExit = true
continue
}
if num == r.EndTime {
dateArr[nk] = append(dateArr[nk], num)
isExit = false
continue
}
if isExit {
dateArr[nk] = append(dateArr[nk], num)
}
}
}
}
}
for dkey, dar := range dateArr {
newArrList := SortInt64(sliceUtil.RemoveDuplicateElementInt64(dar)) // 排序
sArr := make([][]int64, 0)
ss := make([]int64, 0)
for i := 0; i < len(newArrList); i++ {
ss = append(ss, newArrList[i])
if ((i + 1) < len(newArrList)) && (newArrList[i+1]-1) != newArrList[i] {
sArr = append(sArr, ss)
ss = make([]int64, 0)
}
if (i + 1) == len(newArrList) {
sArr = append(sArr, ss)
}
}
// 获取时间区域,最大/最小值
for _, sar := range sArr {
finalData[dkey] = append(finalData[dkey], RecordTime{
StartTime: sar[0],
EndTime: sar[len(sar)-1],
})
}
}
return finalData
}
func SortInt64(int64Values []int64) []int64 {
int64AsIntValues := make([]int, len(int64Values))
res := make([]int64, len(int64Values))
for i, val := range int64Values {
int64AsIntValues[i] = int(val)
}
sort.Ints(int64AsIntValues)
for i, v := range int64AsIntValues {
val := int64(v)
res[i] = val
}
return res
}