date_util.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package utils
  2. import (
  3. "time"
  4. )
  5. // 定义时间格式常量
  6. const (
  7. YearMonthDay = "2006-01-02" // yyyy-MM-dd
  8. YearMonthDayTime = "2006-01-02 15:04:05" // yyyy-MM-dd HH:mm:ss
  9. MonthDay = "01-02" // MM-dd
  10. DayMonthYear = "02-01-2006" // dd-MM-yyyy
  11. YearMonth = "2006-01" // yyyy-MM
  12. FullDate = "Monday, 02-Jan-06 15:04:05 PST" // 完整日期:例如:Monday, 02-Jan-06 15:04:05 PST
  13. )
  14. // GetPreYearTime 获取当前时间 前n年的时间 返回yyyy-MM-dd 格式的时间
  15. func GetPreYearTime(n int) string {
  16. // 获取当前时间
  17. now := time.Now()
  18. // 计算前n年的时间
  19. preYearTime := now.AddDate(-n, 0, 0)
  20. // 格式化时间
  21. return preYearTime.Format("2006-01-02")
  22. }
  23. // IsMoreThanOneDay 判断两个yyyy-MM-dd类型的时间,相差是否大于1天
  24. func IsMoreThanOneDay(startDate, endDate string) bool {
  25. startTime, _ := time.Parse("2006-01-02", startDate)
  26. endTime, _ := time.Parse("2006-01-02", endDate)
  27. diff := endTime.Sub(startTime)
  28. days := diff.Hours() / 24
  29. return days > 1
  30. }
  31. // GetNextDay 获取 yyyy-MM-dd类型的时间的下一天
  32. func GetNextDay(date string) string {
  33. t, _ := time.Parse("2006-01-02", date)
  34. nextDay := t.AddDate(0, 0, 1)
  35. return nextDay.Format("2006-01-02")
  36. }
  37. // GetNextDayN 获取 yyyy-MM-dd 类型的时间的下n天
  38. func GetNextDayN(date string, n int) string {
  39. t, _ := time.Parse("2006-01-02", date)
  40. nextDay := t.AddDate(0, 0, n)
  41. return nextDay.Format("2006-01-02")
  42. }
  43. var daysOfMonth = [...]int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
  44. // AddDate 解决 Go time 包 AddDate() 添加年份/月份溢出到下一个月的问题。
  45. // 例如:
  46. //
  47. // 2024-02-29 AddDate(1, 0, 0) 期望结果: 2025-02-28
  48. // 2024-08-31 AddDate(0, 1, 1) 期望结果: 2024-09-30
  49. func AddDate(t time.Time, years, months int) time.Time {
  50. month := t.Month()
  51. // 规范年份和月份
  52. years, months = norm(years, months, 12)
  53. // 计算目标月份
  54. targetMonth := int(month) + months
  55. if targetMonth <= 0 {
  56. // 处理负值月份
  57. targetMonth += 12 * ((-targetMonth)/12 + 1)
  58. }
  59. // 取余计算目标月份
  60. targetMonth = (targetMonth-1)%12 + 1
  61. // 计算目标年份
  62. targetYear := t.Year() + years + (int(month)+months-1)/12
  63. // 计算目标月份最大天数
  64. maxDayOfTargetMonth := daysOfMonth[targetMonth-1]
  65. if isLeap(targetYear) && targetMonth == 2 {
  66. maxDayOfTargetMonth++ // 闰年2月多一天
  67. }
  68. // 计算目标日期
  69. targetDay := t.Day()
  70. if targetDay > maxDayOfTargetMonth {
  71. // 如果目标日期超出该月的天数,设置为该月的最后一天
  72. targetDay = maxDayOfTargetMonth
  73. }
  74. // 返回新的日期
  75. return time.Date(targetYear, time.Month(targetMonth), targetDay, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
  76. }
  77. // norm 规范化年份和月份
  78. func norm(hi, lo, base int) (nhi, nlo int) {
  79. if lo < 0 {
  80. n := (-lo-1)/base + 1
  81. hi -= n
  82. lo += n * base
  83. }
  84. if lo >= base {
  85. n := lo / base
  86. hi += n
  87. lo -= n * base
  88. }
  89. return hi, lo
  90. }
  91. // isLeap 判断是否为闰年
  92. func isLeap(year int) bool {
  93. return year%4 == 0 && (year%100 != 0 || year%400 == 0)
  94. }
  95. // StringToTime string 类型时间 转换为 time.Time 类型
  96. func StringToTime(date string) time.Time {
  97. t, _ := time.Parse("2006-01-02", date)
  98. return t
  99. }
  100. // TimeToString time.Time 类型时间 转换为 string 类型
  101. func TimeToString(t time.Time, format string) string {
  102. formattedTime := t.Format(format)
  103. return formattedTime
  104. }
  105. // CompareDate 判断传入的两个字符串时间的前后顺序
  106. func CompareDate(data1, data2 string) bool {
  107. t1, _ := time.Parse("2006-01-02", data1)
  108. t2, _ := time.Parse("2006-01-02", data2)
  109. return !t1.After(t2)
  110. }