苏州瑞玛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.

540 lines
12 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package utils
  2. import (
  3. "errors"
  4. "fmt"
  5. "log"
  6. "math"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. var TimezoneLocation *time.Location
  12. type ITimer struct {
  13. *time.Timer
  14. name string
  15. exited bool
  16. isRunning bool
  17. d time.Duration
  18. fn func()
  19. }
  20. func itimerDefaultFunc() {}
  21. func NewTimer(d time.Duration) *ITimer {
  22. tm := &ITimer{
  23. Timer: time.NewTimer(d),
  24. exited: false,
  25. isRunning: true,
  26. d: d,
  27. fn: itimerDefaultFunc,
  28. }
  29. tm.Pause()
  30. return tm
  31. }
  32. func (tm *ITimer) SetName(nm string) {
  33. tm.name = nm
  34. }
  35. func (tm *ITimer) Name() string {
  36. return tm.name
  37. }
  38. func (tm *ITimer) Exit() bool {
  39. tm.exited = tm.Timer.Reset(0)
  40. return tm.exited
  41. }
  42. func (tm *ITimer) IsExit() bool {
  43. return tm.exited
  44. }
  45. func (tm *ITimer) reset() bool {
  46. if tm.exited {
  47. return false
  48. }
  49. tm.isRunning = true
  50. return tm.Timer.Reset(tm.d)
  51. }
  52. func (tm *ITimer) Pause() bool {
  53. tm.isRunning = false
  54. return tm.Timer.Reset(time.Duration(math.MaxInt64))
  55. }
  56. func (tm *ITimer) Continue() bool {
  57. tm.isRunning = true
  58. return tm.reset()
  59. }
  60. func (tm *ITimer) IsRunning() bool {
  61. if tm.exited {
  62. return false
  63. }
  64. return tm.isRunning
  65. }
  66. func (tm *ITimer) SetFunc(fn func()) {
  67. tm.fn = fn
  68. }
  69. func (tm *ITimer) NowExecFunc() {
  70. if tm.fn != nil {
  71. go tm.fn()
  72. }
  73. tm.reset()
  74. }
  75. func (tm *ITimer) Run() {
  76. for {
  77. select {
  78. case <-tm.C:
  79. if tm.IsExit() {
  80. tm.isRunning = false
  81. return
  82. }
  83. tm.reset()
  84. if tm.fn != nil {
  85. go tm.fn()
  86. }
  87. }
  88. }
  89. }
  90. //format time like java, such as: yyyy-MM-dd HH:mm:ss
  91. func TimeFormat(t time.Time, format string) string {
  92. //year
  93. if strings.ContainsAny(format, "y") {
  94. year := strconv.Itoa(t.Year())
  95. if strings.Count(format, "yy") == 1 && strings.Count(format, "y") == 2 {
  96. format = strings.Replace(format, "yy", year[2:], 1)
  97. } else if strings.Count(format, "yyyy") == 1 && strings.Count(format, "y") == 4 {
  98. format = strings.Replace(format, "yyyy", year, 1)
  99. } else {
  100. log.Fatalln("format year error! please 'yyyy' or 'yy'")
  101. }
  102. }
  103. //month
  104. if strings.ContainsAny(format, "M") {
  105. var month string
  106. if int(t.Month()) < 10 {
  107. month = "0" + strconv.Itoa(int(t.Month()))
  108. } else {
  109. month = strconv.Itoa(int(t.Month()))
  110. }
  111. if strings.Count(format, "MM") == 1 && strings.Count(format, "M") == 2 {
  112. format = strings.Replace(format, "MM", month, 1)
  113. } else {
  114. log.Fatalln("format month error! please 'MM'")
  115. }
  116. }
  117. //day
  118. if strings.ContainsAny(format, "d") {
  119. var day string
  120. if t.Day() < 10 {
  121. day = "0" + strconv.Itoa(t.Day())
  122. } else {
  123. day = strconv.Itoa(t.Day())
  124. }
  125. if strings.Count(format, "dd") == 1 && strings.Count(format, "d") == 2 {
  126. format = strings.Replace(format, "dd", day, 1)
  127. } else {
  128. log.Fatalln("format day error! please 'dd'")
  129. }
  130. }
  131. //hour
  132. if strings.ContainsAny(format, "H") {
  133. var hour string
  134. if t.Hour() < 10 {
  135. hour = "0" + strconv.Itoa(t.Hour())
  136. } else {
  137. hour = strconv.Itoa(t.Hour())
  138. }
  139. if strings.Count(format, "HH") == 1 && strings.Count(format, "H") == 2 {
  140. format = strings.Replace(format, "HH", hour, 1)
  141. } else {
  142. log.Fatalln("format hour error! please 'HH'")
  143. }
  144. }
  145. //minute
  146. if strings.ContainsAny(format, "m") {
  147. var minute string
  148. if t.Minute() < 10 {
  149. minute = "0" + strconv.Itoa(t.Minute())
  150. } else {
  151. minute = strconv.Itoa(t.Minute())
  152. }
  153. if strings.Count(format, "mm") == 1 && strings.Count(format, "m") == 2 {
  154. format = strings.Replace(format, "mm", minute, 1)
  155. } else {
  156. log.Fatalln("format minute error! please 'mm'")
  157. }
  158. }
  159. //second
  160. if strings.ContainsAny(format, "s") {
  161. var second string
  162. if t.Second() < 10 {
  163. second = "0" + strconv.Itoa(t.Second())
  164. } else {
  165. second = strconv.Itoa(t.Second())
  166. }
  167. if strings.Count(format, "ss") == 1 && strings.Count(format, "s") == 2 {
  168. format = strings.Replace(format, "ss", second, 1)
  169. } else {
  170. log.Fatalln("format second error! please 'ss'")
  171. }
  172. }
  173. return format
  174. }
  175. //2007-11-23 10:02:14/20071123100214
  176. func TimeParse(str string) (time.Time, error) {
  177. ll := len(str)
  178. if ll == 19 {
  179. loc, _ := time.LoadLocation("Local")
  180. return time.ParseInLocation("2006-01-02 15:04:05", str, loc)
  181. } else if ll == 14 {
  182. loc, _ := time.LoadLocation("Local")
  183. return time.ParseInLocation("20060102150405", str, loc)
  184. }
  185. return time.Time{}, errors.New("str len is error")
  186. }
  187. //17:02:03/170203
  188. func TimeParseHHmmss(str string) (time.Time, error) {
  189. ll := len(str)
  190. if ll != 8 && ll != 6 {
  191. return time.Time{}, errors.New("input str is error")
  192. }
  193. if ll == 8 {
  194. return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str))
  195. }
  196. return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str))
  197. }
  198. //17:02/1702
  199. func TimeParseHHmm(str string) (time.Time, error) {
  200. ll := len(str)
  201. if ll != 5 && ll != 4 {
  202. return time.Time{}, errors.New("input str is error")
  203. }
  204. if ll == 5 {
  205. return TimeParse(TimeFormat(time.Now(), "yyyy-MM-dd "+str+":00"))
  206. }
  207. return TimeParse(TimeFormat(time.Now(), "yyyyMMdd"+str+"00"))
  208. }
  209. //2007-05-69/20070569
  210. func TimeParseyyyyMMdd(str string) (time.Time, error) {
  211. ll := len(str)
  212. if ll != 10 && ll != 8 {
  213. return time.Time{}, errors.New("input str is error")
  214. }
  215. if ll == 10 {
  216. return TimeParse(TimeFormat(time.Now(), str+" 00:00:00"))
  217. }
  218. return TimeParse(TimeFormat(time.Now(), str+"000000"))
  219. }
  220. //计算时间差返回秒级 样例: T1 = 16:00 t2 = 08:00
  221. func Timelen(t1 string, t2 string) (int, error) {
  222. var time1 int64
  223. var time2 int64
  224. len1 := len(t1)
  225. if len1 != 4 && len1 != 5 {
  226. return 0, errors.New("input str is error")
  227. }
  228. len2 := len(t2)
  229. if len2 != 4 && len2 != 5 {
  230. return 0, errors.New("input str is error")
  231. }
  232. tem1, _ := TimeParseHHmm(t1)
  233. time1 = tem1.Unix()
  234. tem2, _ := TimeParseHHmm(t2)
  235. time2 = tem2.Unix()
  236. timelen := time1 - time2
  237. return int(timelen), nil
  238. }
  239. //获取某一天的0点时间
  240. func GetZeroTime(d time.Time) time.Time {
  241. now := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
  242. return now
  243. }
  244. //返回格式:例如2016-05-01 00:00:00的时间戳到2016-06-01 00:00:00的时间戳
  245. func TimeReturnMonth(now time.Time) (firstMonth string, lastMonth string) {
  246. currentYear, currentMonth, _ := now.Date()
  247. currentLocation := now.Location()
  248. firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
  249. lastOfMonth := firstOfMonth.AddDate(0, 1, 0).Add(time.Second * -1)
  250. return TimeFormat(firstOfMonth, "yyyyMMdd"), TimeFormat(lastOfMonth, "yyyyMMdd")
  251. }
  252. // 获取两个时间点之间的天数
  253. func GetCrossDays(t1, t2 time.Time) (days int) {
  254. var (
  255. y1, d1, y2, d2 int
  256. m1, m2 time.Month
  257. date1, date2 time.Time
  258. )
  259. days = 0
  260. if t1.Unix() >= t2.Unix() {
  261. return
  262. }
  263. y1, m1, d1 = t1.Date()
  264. y2, m2, d2 = t2.Date()
  265. date1 = time.Date(y1, m1, d1, 0, 0, 0, 0, time.UTC)
  266. date2 = time.Date(y2, m2, d2, 0, 0, 0, 0, time.UTC)
  267. days = int(date2.Sub(date1).Hours() / 24)
  268. return
  269. }
  270. // 获取时间点的日期,以年月日字符类型数据返回
  271. func GetYMDString(t time.Time) (ymd string) {
  272. var (
  273. y1, d1 int
  274. m1 time.Month
  275. )
  276. y1, m1, d1 = t.Date()
  277. ymd = fmt.Sprintf("%04d", y1) + fmt.Sprintf("%02d", int(m1)) + fmt.Sprintf("%02d", d1)
  278. return
  279. }
  280. func ParseWeekIndex(date time.Time) int {
  281. dateStr := date.Format("2006-01-02")
  282. dateStr = dateStr[:8] + "01"
  283. firstDay, _ := time.ParseInLocation("2006-01-02", dateStr, TimezoneLocation)
  284. firstWeekDay := firstDay.Weekday()
  285. weekDay := date.Weekday()
  286. for i := 1; i < 6; i++ {
  287. date = date.AddDate(0, 0, -7)
  288. if date.Before(firstDay) {
  289. if weekDay >= firstWeekDay {
  290. return i
  291. }
  292. return i + 1
  293. }
  294. }
  295. return 0
  296. }
  297. // 获取线段上两个时间点之间的Duration
  298. func GetDuration(startTime, endTime time.Time, EffFactor float64) (duration time.Duration) {
  299. var seconds float64
  300. if endTime.Unix() <= startTime.Unix() {
  301. duration = 0
  302. return
  303. }
  304. if EffFactor <= 0 {
  305. EffFactor = 1
  306. }
  307. seconds = endTime.Sub(startTime).Seconds() * EffFactor
  308. duration = time.Duration(seconds) * time.Second
  309. return
  310. }
  311. func ZellerFunction2Week(year, month, day uint16) int {
  312. var y, m, c uint16
  313. if month >= 3 {
  314. m = month
  315. y = year % 100
  316. c = year / 100
  317. } else {
  318. m = month + 12
  319. y = (year - 1) % 100
  320. c = (year - 1) / 100
  321. }
  322. week := y + (y / 4) + (c / 4) - 2*c + ((26 * (m + 1)) / 10) + day - 1
  323. if week < 0 {
  324. week = 7 - (-week)%7
  325. } else {
  326. week = week % 7
  327. }
  328. which_week := int(week)
  329. return which_week
  330. }
  331. //判断时间是当年的第几周
  332. func WeekByDate(t time.Time) (int, int, time.Month) {
  333. var yearFirstDay time.Time
  334. var yearDay int
  335. //计算当前时间是周几
  336. year, month, day := t.Date()
  337. firstWeek := ZellerFunction2Week(uint16(year), uint16(month), uint16(day))
  338. dayLen := 7 - firstWeek
  339. //计算周日的时间,防止跨年
  340. startDate := t.AddDate(0, 0, dayLen)
  341. nextyear, nextmonth, _ := startDate.Date()
  342. //判断是否跨年
  343. if nextyear > year {
  344. year = nextyear
  345. month = nextmonth
  346. yearDay = startDate.YearDay()
  347. yearFirstDay = startDate.AddDate(0, 0, -yearDay+1)
  348. } else {
  349. yearDay = t.YearDay()
  350. yearFirstDay = t.AddDate(0, 0, -yearDay+1)
  351. }
  352. firstDayInWeek := int(yearFirstDay.Weekday())
  353. //今年第一周有几天
  354. firstWeekDays := 1
  355. if firstDayInWeek != 0 {
  356. firstWeekDays = 7 - firstDayInWeek + 1
  357. }
  358. var week int
  359. if yearDay <= firstWeekDays {
  360. week = 1
  361. } else {
  362. week = (yearDay-firstWeekDays)/7 + 2
  363. }
  364. return week, year, month
  365. }
  366. //判断时间是当年的第几周
  367. func WeekByDateStr(t time.Time) string {
  368. yearDay := t.YearDay()
  369. yearFirstDay := t.AddDate(0, 0, -yearDay+1)
  370. firstDayInWeek := int(yearFirstDay.Weekday())
  371. //今年第一周有几天
  372. firstWeekDays := 1
  373. if firstDayInWeek != 0 {
  374. firstWeekDays = 7 - firstDayInWeek + 1
  375. }
  376. var week int
  377. if yearDay <= firstWeekDays {
  378. week = 1
  379. } else {
  380. week = (yearDay-firstWeekDays)/7 + 2
  381. }
  382. return fmt.Sprintf("%d.%d", t.Year(), week)
  383. }
  384. type WeekDate struct {
  385. WeekTh string
  386. StartTime time.Time
  387. EndTime time.Time
  388. }
  389. // 将开始时间和结束时间分割为周为单位
  390. func GroupByWeekDate(startTime, endTime time.Time) []WeekDate {
  391. weekDate := make([]WeekDate, 0)
  392. diffDuration := endTime.Sub(startTime)
  393. days := int(math.Ceil(float64(diffDuration/(time.Hour*24)))) + 1
  394. currentWeekDate := WeekDate{}
  395. currentWeekDate.WeekTh = WeekByDateStr(endTime)
  396. currentWeekDate.EndTime = endTime
  397. currentWeekDay := int(endTime.Weekday())
  398. if currentWeekDay == 0 {
  399. currentWeekDay = 7
  400. }
  401. currentWeekDate.StartTime = endTime.AddDate(0, 0, -currentWeekDay+1)
  402. nextWeekEndTime := currentWeekDate.StartTime
  403. weekDate = append(weekDate, currentWeekDate)
  404. for i := 0; i < (days-currentWeekDay)/7; i++ {
  405. weekData := WeekDate{}
  406. weekData.EndTime = nextWeekEndTime
  407. weekData.StartTime = nextWeekEndTime.AddDate(0, 0, -7)
  408. weekData.WeekTh = WeekByDateStr(weekData.StartTime)
  409. nextWeekEndTime = weekData.StartTime
  410. weekDate = append(weekDate, weekData)
  411. }
  412. if lastDays := (days - currentWeekDay) % 7; lastDays > 0 {
  413. lastData := WeekDate{}
  414. lastData.EndTime = nextWeekEndTime
  415. lastData.StartTime = nextWeekEndTime.AddDate(0, 0, -lastDays)
  416. lastData.WeekTh = WeekByDateStr(lastData.StartTime)
  417. weekDate = append(weekDate, lastData)
  418. }
  419. return weekDate
  420. }
  421. //周一0点
  422. func WeekDayMondayZeroTs(now time.Time) time.Time {
  423. offset := int(time.Monday - now.Weekday())
  424. if offset > 0 {
  425. offset = -6
  426. }
  427. weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
  428. return weekStart
  429. }
  430. func WeekDaySaturdayZeroTs(now time.Time) time.Time {
  431. offset := int(time.Monday - now.Weekday())
  432. if offset > 0 {
  433. offset = -6
  434. }
  435. offset += 5
  436. weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
  437. return weekStart
  438. }
  439. func WeekDaySundayZeroTs(now time.Time) time.Time {
  440. offset := int(time.Monday - now.Weekday())
  441. if offset > 0 {
  442. offset = -6
  443. }
  444. offset += 6
  445. weekStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
  446. return weekStart
  447. }