code.gitea.io/gitea@v1.22.3/modules/timeutil/since.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package timeutil 5 6 import ( 7 "fmt" 8 "html/template" 9 "strings" 10 "time" 11 12 "code.gitea.io/gitea/modules/setting" 13 "code.gitea.io/gitea/modules/translation" 14 ) 15 16 // Seconds-based time units 17 const ( 18 Minute = 60 19 Hour = 60 * Minute 20 Day = 24 * Hour 21 Week = 7 * Day 22 Month = 30 * Day 23 Year = 12 * Month 24 ) 25 26 func computeTimeDiffFloor(diff int64, lang translation.Locale) (int64, string) { 27 var diffStr string 28 switch { 29 case diff <= 0: 30 diff = 0 31 diffStr = lang.TrString("tool.now") 32 case diff < 2: 33 diff = 0 34 diffStr = lang.TrString("tool.1s") 35 case diff < 1*Minute: 36 diffStr = lang.TrString("tool.seconds", diff) 37 diff = 0 38 39 case diff < 2*Minute: 40 diff -= 1 * Minute 41 diffStr = lang.TrString("tool.1m") 42 case diff < 1*Hour: 43 diffStr = lang.TrString("tool.minutes", diff/Minute) 44 diff -= diff / Minute * Minute 45 46 case diff < 2*Hour: 47 diff -= 1 * Hour 48 diffStr = lang.TrString("tool.1h") 49 case diff < 1*Day: 50 diffStr = lang.TrString("tool.hours", diff/Hour) 51 diff -= diff / Hour * Hour 52 53 case diff < 2*Day: 54 diff -= 1 * Day 55 diffStr = lang.TrString("tool.1d") 56 case diff < 1*Week: 57 diffStr = lang.TrString("tool.days", diff/Day) 58 diff -= diff / Day * Day 59 60 case diff < 2*Week: 61 diff -= 1 * Week 62 diffStr = lang.TrString("tool.1w") 63 case diff < 1*Month: 64 diffStr = lang.TrString("tool.weeks", diff/Week) 65 diff -= diff / Week * Week 66 67 case diff < 2*Month: 68 diff -= 1 * Month 69 diffStr = lang.TrString("tool.1mon") 70 case diff < 1*Year: 71 diffStr = lang.TrString("tool.months", diff/Month) 72 diff -= diff / Month * Month 73 74 case diff < 2*Year: 75 diff -= 1 * Year 76 diffStr = lang.TrString("tool.1y") 77 default: 78 diffStr = lang.TrString("tool.years", diff/Year) 79 diff -= (diff / Year) * Year 80 } 81 return diff, diffStr 82 } 83 84 // MinutesToFriendly returns a user friendly string with number of minutes 85 // converted to hours and minutes. 86 func MinutesToFriendly(minutes int, lang translation.Locale) string { 87 duration := time.Duration(minutes) * time.Minute 88 return TimeSincePro(time.Now().Add(-duration), lang) 89 } 90 91 // TimeSincePro calculates the time interval and generate full user-friendly string. 92 func TimeSincePro(then time.Time, lang translation.Locale) string { 93 return timeSincePro(then, time.Now(), lang) 94 } 95 96 func timeSincePro(then, now time.Time, lang translation.Locale) string { 97 diff := now.Unix() - then.Unix() 98 99 if then.After(now) { 100 return lang.TrString("tool.future") 101 } 102 if diff == 0 { 103 return lang.TrString("tool.now") 104 } 105 106 var timeStr, diffStr string 107 for { 108 if diff == 0 { 109 break 110 } 111 112 diff, diffStr = computeTimeDiffFloor(diff, lang) 113 timeStr += ", " + diffStr 114 } 115 return strings.TrimPrefix(timeStr, ", ") 116 } 117 118 func timeSinceUnix(then, now time.Time, _ translation.Locale) template.HTML { 119 friendlyText := then.Format("2006-01-02 15:04:05 -07:00") 120 121 // document: https://github.com/github/relative-time-element 122 attrs := `tense="past"` 123 isFuture := now.Before(then) 124 if isFuture { 125 attrs = `tense="future"` 126 } 127 128 // declare data-tooltip-content attribute to switch from "title" tooltip to "tippy" tooltip 129 htm := fmt.Sprintf(`<relative-time prefix="" %s datetime="%s" data-tooltip-content data-tooltip-interactive="true">%s</relative-time>`, 130 attrs, then.Format(time.RFC3339), friendlyText) 131 return template.HTML(htm) 132 } 133 134 // TimeSince renders relative time HTML given a time.Time 135 func TimeSince(then time.Time, lang translation.Locale) template.HTML { 136 if setting.UI.PreferredTimestampTense == "absolute" { 137 return DateTime("full", then) 138 } 139 return timeSinceUnix(then, time.Now(), lang) 140 } 141 142 // TimeSinceUnix renders relative time HTML given a TimeStamp 143 func TimeSinceUnix(then TimeStamp, lang translation.Locale) template.HTML { 144 return TimeSince(then.AsLocalTime(), lang) 145 }