util.go 5.0 KB

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