-
Notifications
You must be signed in to change notification settings - Fork 6
/
timeago.go
155 lines (122 loc) · 3.43 KB
/
timeago.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package timeago
import (
"log"
"math"
"strconv"
"time"
)
var cachedJsonResults = map[string]lang{}
var globalOptions = []string{}
// Parse coverts given datetime into `x time ago` format.
// First argument can have 3 types:
// 1. int (Unix timestamp)
// 2. time.Time (Type from Go time package)
// 3. string (Datetime string in format 'YYYY-MM-DD HH:MM:SS')
func Parse(datetime interface{}, options ...string) string {
var input time.Time
switch date := datetime.(type) {
case int:
input = parseTimestampIntoTime(date)
case string:
input = parseStrIntoTime(date)
default:
input = datetime.(time.Time)
}
globalOptions = options
return parseInput(input)
}
func parseStrIntoTime(datetime string) time.Time {
if locationIsNotSet() {
parsedTime, _ := time.Parse("2006-01-02 15:04:05", datetime)
return parsedTime
}
location, err := time.LoadLocation(config.Location)
if err != nil {
log.Fatalf("Error in timeago package: %v", err)
}
parsedTime, _ := time.ParseInLocation("2006-01-02 15:04:05", datetime, location)
return parsedTime
}
func parseInput(datetime time.Time) string {
now := time.Now()
if locationIsSet() {
now = applyLocationToTime(now)
}
seconds := now.Sub(datetime).Seconds()
if seconds < 0 {
enableOption("upcoming")
seconds = math.Abs(seconds)
}
switch {
case seconds < 60 && optionIsEnabled("online"):
return trans().Online
case seconds < 0:
return getWords("seconds", 0)
}
return calculateTheResult(int(seconds))
}
func applyLocationToTime(datetime time.Time) time.Time {
location, err := time.LoadLocation(config.Location)
if err != nil {
log.Fatalf("Location error in timeago package: %v\n", err)
}
return datetime.In(location)
}
func calculateTheResult(seconds int) string {
minutes, hours, days, weeks, months, years := getTimeCalculations(float64(seconds))
switch {
case optionIsEnabled("online") && seconds < 60:
return trans().Online
case optionIsEnabled("justNow") && seconds < 60:
return trans().JustNow
case seconds < 60:
return getWords("seconds", seconds)
case minutes < 60:
return getWords("minutes", minutes)
case hours < 24:
return getWords("hours", hours)
case days < 7:
return getWords("days", days)
case weeks < 4:
return getWords("weeks", weeks)
case months < 12:
if months == 0 {
months = 1
}
return getWords("months", months)
}
return getWords("years", years)
}
func getTimeCalculations(seconds float64) (int, int, int, int, int, int) {
minutes := math.Round(seconds / 60)
hours := math.Round(seconds / 3600)
days := math.Round(seconds / 86400)
weeks := math.Round(seconds / 604800)
months := math.Round(seconds / 2629440)
years := math.Round(seconds / 31553280)
return int(minutes), int(hours), int(days), int(weeks), int(months), int(years)
}
// getWords decides rather the word must be singular or plural,
// and depending on the result it adds the correct word after
// the time number
func getWords(timeKind string, num int) string {
form := getLanguageForm(num)
time := getTimeTranslations()
translation := time[timeKind][form]
result := strconv.Itoa(num) + " " + translation
if optionIsEnabled("noSuffix") || optionIsEnabled("upcoming") {
return result
}
return overwriteOutput(result)
}
func optionIsEnabled(searchOption string) bool {
for _, option := range globalOptions {
if option == searchOption {
return true
}
}
return false
}
func enableOption(option string) {
globalOptions = append(globalOptions, option)
}