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.

364 lines
7.7 KiB

  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. }