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.

since.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package timeutil
  5. import (
  6. "fmt"
  7. "html/template"
  8. "strings"
  9. "time"
  10. "code.gitea.io/gitea/modules/setting"
  11. "github.com/Unknwon/i18n"
  12. )
  13. // Seconds-based time units
  14. const (
  15. Minute = 60
  16. Hour = 60 * Minute
  17. Day = 24 * Hour
  18. Week = 7 * Day
  19. Month = 30 * Day
  20. Year = 12 * Month
  21. )
  22. func computeTimeDiff(diff int64, lang string) (int64, string) {
  23. diffStr := ""
  24. switch {
  25. case diff <= 0:
  26. diff = 0
  27. diffStr = i18n.Tr(lang, "tool.now")
  28. case diff < 2:
  29. diff = 0
  30. diffStr = i18n.Tr(lang, "tool.1s")
  31. case diff < 1*Minute:
  32. diffStr = i18n.Tr(lang, "tool.seconds", diff)
  33. diff = 0
  34. case diff < 2*Minute:
  35. diff -= 1 * Minute
  36. diffStr = i18n.Tr(lang, "tool.1m")
  37. case diff < 1*Hour:
  38. diffStr = i18n.Tr(lang, "tool.minutes", diff/Minute)
  39. diff -= diff / Minute * Minute
  40. case diff < 2*Hour:
  41. diff -= 1 * Hour
  42. diffStr = i18n.Tr(lang, "tool.1h")
  43. case diff < 1*Day:
  44. diffStr = i18n.Tr(lang, "tool.hours", diff/Hour)
  45. diff -= diff / Hour * Hour
  46. case diff < 2*Day:
  47. diff -= 1 * Day
  48. diffStr = i18n.Tr(lang, "tool.1d")
  49. case diff < 1*Week:
  50. diffStr = i18n.Tr(lang, "tool.days", diff/Day)
  51. diff -= diff / Day * Day
  52. case diff < 2*Week:
  53. diff -= 1 * Week
  54. diffStr = i18n.Tr(lang, "tool.1w")
  55. case diff < 1*Month:
  56. diffStr = i18n.Tr(lang, "tool.weeks", diff/Week)
  57. diff -= diff / Week * Week
  58. case diff < 2*Month:
  59. diff -= 1 * Month
  60. diffStr = i18n.Tr(lang, "tool.1mon")
  61. case diff < 1*Year:
  62. diffStr = i18n.Tr(lang, "tool.months", diff/Month)
  63. diff -= diff / Month * Month
  64. case diff < 2*Year:
  65. diff -= 1 * Year
  66. diffStr = i18n.Tr(lang, "tool.1y")
  67. default:
  68. diffStr = i18n.Tr(lang, "tool.years", diff/Year)
  69. diff -= (diff / Year) * Year
  70. }
  71. return diff, diffStr
  72. }
  73. // MinutesToFriendly returns a user friendly string with number of minutes
  74. // converted to hours and minutes.
  75. func MinutesToFriendly(minutes int, lang string) string {
  76. duration := time.Duration(minutes) * time.Minute
  77. return TimeSincePro(time.Now().Add(-duration), lang)
  78. }
  79. // TimeSincePro calculates the time interval and generate full user-friendly string.
  80. func TimeSincePro(then time.Time, lang string) string {
  81. return timeSincePro(then, time.Now(), lang)
  82. }
  83. func timeSincePro(then, now time.Time, lang string) string {
  84. diff := now.Unix() - then.Unix()
  85. if then.After(now) {
  86. return i18n.Tr(lang, "tool.future")
  87. }
  88. if diff == 0 {
  89. return i18n.Tr(lang, "tool.now")
  90. }
  91. var timeStr, diffStr string
  92. for {
  93. if diff == 0 {
  94. break
  95. }
  96. diff, diffStr = computeTimeDiff(diff, lang)
  97. timeStr += ", " + diffStr
  98. }
  99. return strings.TrimPrefix(timeStr, ", ")
  100. }
  101. func timeSince(then, now time.Time, lang string) string {
  102. return timeSinceUnix(then.Unix(), now.Unix(), lang)
  103. }
  104. func timeSinceUnix(then, now int64, lang string) string {
  105. lbl := "tool.ago"
  106. diff := now - then
  107. if then > now {
  108. lbl = "tool.from_now"
  109. diff = then - now
  110. }
  111. if diff <= 0 {
  112. return i18n.Tr(lang, "tool.now")
  113. }
  114. _, diffStr := computeTimeDiff(diff, lang)
  115. return i18n.Tr(lang, lbl, diffStr)
  116. }
  117. // RawTimeSince retrieves i18n key of time since t
  118. func RawTimeSince(t time.Time, lang string) string {
  119. return timeSince(t, time.Now(), lang)
  120. }
  121. // TimeSince calculates the time interval and generate user-friendly string.
  122. func TimeSince(then time.Time, lang string) template.HTML {
  123. return htmlTimeSince(then, time.Now(), lang)
  124. }
  125. func htmlTimeSince(then, now time.Time, lang string) template.HTML {
  126. return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
  127. then.In(setting.DefaultUILocation).Format(GetTimeFormat(lang)),
  128. timeSince(then, now, lang)))
  129. }
  130. // TimeSinceUnix calculates the time interval and generate user-friendly string.
  131. func TimeSinceUnix(then TimeStamp, lang string) template.HTML {
  132. return htmlTimeSinceUnix(then, TimeStamp(time.Now().Unix()), lang)
  133. }
  134. func htmlTimeSinceUnix(then, now TimeStamp, lang string) template.HTML {
  135. return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
  136. then.FormatInLocation(GetTimeFormat(lang), setting.DefaultUILocation),
  137. timeSinceUnix(int64(then), int64(now), lang)))
  138. }