util.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package util
  2. import (
  3. "fmt"
  4. "math"
  5. "time"
  6. "gitee.com/xuyiping_admin/pkg/xerr"
  7. )
  8. const (
  9. LocationName = "Asia/Shanghai"
  10. LayoutTime = "2006-01-02 15:04:05"
  11. Layout = "2006-01-02"
  12. LayoutMonth = "2006-01"
  13. )
  14. // TimeParseLocalUnix 获取当天零点的时间戳
  15. // eg 2023-02-22 => 1676995200
  16. func TimeParseLocalUnix(DayTime string) int64 {
  17. value := DayTime
  18. if len(DayTime) <= 11 {
  19. value = fmt.Sprintf("%s 00:00:00", DayTime)
  20. }
  21. loc, _ := time.LoadLocation("Local")
  22. theTime, _ := time.ParseInLocation(LayoutTime, value, loc)
  23. return theTime.Unix()
  24. }
  25. // TimeParseLocalEndUnix 获取当天24点的时间戳
  26. // eg 2023-02-22 => 1676995200
  27. func TimeParseLocalEndUnix(DayTime string) int64 {
  28. value := DayTime
  29. if len(DayTime) <= 11 {
  30. value = fmt.Sprintf("%s 23:59:59", DayTime)
  31. }
  32. loc, _ := time.LoadLocation("Local")
  33. theTime, _ := time.ParseInLocation(LayoutTime, value, loc)
  34. return theTime.Unix()
  35. }
  36. // ConvertParseLocalUnix 字符串转换当天时间戳
  37. // eg 15:04:05 => 1676998245
  38. func ConvertParseLocalUnix(timeParse string) (int64, error) {
  39. loc, err := time.LoadLocation("Local")
  40. if err != nil {
  41. return 0, err
  42. }
  43. value := fmt.Sprintf("%s %s", time.Now().Format(Layout), timeParse)
  44. theTime, err := time.ParseInLocation(LayoutTime, value, loc)
  45. if err != nil {
  46. return 0, err
  47. }
  48. return theTime.Unix(), nil
  49. }
  50. // GetMonthRemainDay 获取当前月还剩几天
  51. func GetMonthRemainDay() int {
  52. now := time.Now()
  53. lastDayOfMonth := time.Date(now.Year(), now.Month()+1, 0, 23, 59, 59, 999999999, now.Location())
  54. return int(lastDayOfMonth.Sub(now).Hours()/24) + 1
  55. }
  56. // Ceil 向上取整函数
  57. func Ceil(x float64) float64 {
  58. // 使用 math.Floor 计算小于或等于 x 的最大整数
  59. // 然后检查 x 是否为整数,如果不是,则结果加 1
  60. // 注意:math.Floor 返回的是 float64 类型,所以我们需要进行比较
  61. // 来确定是否需要加 1
  62. intPart := math.Floor(x)
  63. if x-intPart > 0 {
  64. return intPart + 1
  65. }
  66. return intPart
  67. }
  68. // GetLastDayOfMonth
  69. // 接受一个字符串形式的月份(如 "2024-12"),
  70. // 并返回该月份的最后一天的日期。
  71. func GetLastDayOfMonth(month string) (string, error) {
  72. // 解析传入的月份
  73. layout := "2006-01"
  74. t, err := time.Parse(layout, month)
  75. if err != nil {
  76. return "", err // 如果解析失败,返回错误
  77. }
  78. // 获取下个月的第一天
  79. nextMonth := t.AddDate(0, 1, 0)
  80. // 返回上个月的最后一天
  81. lastDay := nextMonth.AddDate(0, 0, -1)
  82. return lastDay.Format(Layout), nil
  83. }
  84. // GetMonthsInRange
  85. // 接受两个字符串形式的月份(如 "2024-01" 到 "2024-12"),
  86. // 并返回一个包含这两个月份之间所有月份的字符串切片。
  87. func GetMonthsInRange(startMonth, endMonth string) ([]string, error) {
  88. // 解析起始月份
  89. startLayout := "2006-01"
  90. startTime, err := time.Parse(startLayout, startMonth)
  91. if err != nil {
  92. return nil, err
  93. }
  94. // 解析结束月份
  95. endTime, err := time.Parse(startLayout, endMonth)
  96. if err != nil {
  97. return nil, err
  98. }
  99. // 初始化结果切片
  100. var months []string
  101. // 循环添加每个月份直到达到或超过结束月份
  102. for curr := startTime; curr.Before(endTime) || curr.Equal(endTime); curr = curr.AddDate(0, 1, 0) {
  103. months = append(months, curr.Format("2006-01"))
  104. }
  105. return months, nil
  106. }
  107. // RoundToTwoDecimals 四舍五入并保留两位小数
  108. func RoundToTwoDecimals(num float64) float64 {
  109. // 使用 math.Round 函数进行四舍五入
  110. // 先乘以 100,然后四舍五入,最后除以 100
  111. return math.Round(num*100) / 100
  112. }
  113. // Get21DayPeriods 获取范围时间内21天周期的切片
  114. // 超过开始时间,继续向前推算,直至凑整21天
  115. func Get21DayPeriods(startDay, endDay string) ([][]string, error) {
  116. startDate, err := time.Parse(Layout, startDay)
  117. if err != nil {
  118. return nil, err
  119. }
  120. endDate, err := time.Parse(Layout, endDay)
  121. if err != nil {
  122. return nil, err
  123. }
  124. if startDate.After(endDate) {
  125. return nil, xerr.Custom("start date is after end date")
  126. }
  127. var periods [][]string
  128. for date := endDate; date.After(startDate); {
  129. // Calculate the end of the current period
  130. periodEnd := date.AddDate(0, 0, -20)
  131. // Append the current period to the result slice
  132. periods = append(periods, []string{periodEnd.Format(Layout), date.Format(Layout)})
  133. // Move on to the next day
  134. date = periodEnd.AddDate(0, 0, -1)
  135. }
  136. reverseRows(periods)
  137. return periods, nil
  138. }
  139. func reverseRows(matrix [][]string) {
  140. // 获取矩阵的行数
  141. rows := len(matrix)
  142. if rows == 0 {
  143. return // 如果矩阵为空,则直接返回
  144. }
  145. // 初始化两个指针,一个指向开始,一个指向末尾
  146. for i, j := 0, rows-1; i < j; i, j = i+1, j-1 {
  147. // 交换当前行和对应行
  148. matrix[i], matrix[j] = matrix[j], matrix[i]
  149. }
  150. }
  151. // GetRangeDayMiddleDay 获取指定日期范围中间的某一天
  152. func GetRangeDayMiddleDay(dateRange []string, middleDay int32) (string, error) {
  153. if len(dateRange) < 2 {
  154. return "", xerr.Custom("date range is not enough")
  155. }
  156. if middleDay < 0 {
  157. return "", xerr.Custom("middle day is not enough")
  158. }
  159. startDate, _ := time.Parse(Layout, dateRange[0])
  160. return startDate.AddDate(0, 0, int(middleDay)-1).Format(Layout), nil
  161. }