date_util.go 3.3 KB

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