Passed
Push — master ( e465b8...c9d870 )
by Serhii
02:51 queued 01:13
created

timeago.go   A

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 55.36%

Importance

Changes 0
Metric Value
cc 30
eloc 85
dl 0
loc 137
ccs 31
cts 56
cp 0.5536
crap 110.0599
rs 10
c 0
b 0
f 0

6 Methods

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