Passed
Push — master ( 918b18...1dbab0 )
by Serhii
03:46 queued 01:59
created

timeago.Parse   A

Complexity

Conditions 5

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 8.9038

Importance

Changes 0
Metric Value
cc 5
eloc 18
dl 0
loc 25
ccs 6
cts 13
cp 0.4615
crap 8.9038
rs 9.0333
c 0
b 0
f 0
nop 2
1
package timeago
2
3
import (
4
	"math"
5
	"strconv"
6
	"time"
7
)
8
9
var cachedJsonResults = map[string]lang{}
10
var globalOptions = []string{}
11
12
// Parse coverts given datetime into `x time ago` format.
13
// First argument can have 3 types:
14
// 1. int (Unix timestamp)
15
// 2. time.Time (Type from Go time package)
16
// 3. string (Datetime string in format 'YYYY-MM-DD HH:MM:SS')
17
func Parse(datetime interface{}, options ...string) string {
18 1
	var input time.Time
19
20 1
	switch date := datetime.(type) {
21
	case int:
22 1
		input = parseTimestampToTime(date)
23
	case string:
24
		if config.Location == "" {
25
			parsedTime, _ := time.Parse("2006-01-02 15:04:05", date)
26
			input = parsedTime
27
		} else {
28
			location, err := time.LoadLocation(config.Location)
29
30
			fatalIfError(err, "Error in timeago package: %v")
31
32
			parsedTime, _ := time.ParseInLocation("2006-01-02 15:04:05", date, location)
33
			input = parsedTime
34
		}
35
	default:
36 1
		input = datetime.(time.Time)
37
	}
38
39 1
	globalOptions = options
40
41 1
	return process(input)
42
}
43
44
func process(datetime time.Time) string {
45 1
	now := time.Now()
46
47 1
	if config.Location != "" {
48
		location, err := time.LoadLocation(config.Location)
49
50
		fatalIfError(err, "Location error in timeago package: %v\n")
51
52
		now = now.In(location)
53
	}
54
55 1
	seconds := now.Sub(datetime).Seconds()
56
57 1
	if seconds < 0 {
58 1
		enableOption("upcoming")
59 1
		seconds = math.Abs(seconds)
60
	}
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(int(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") || optionIsEnabled("upcoming") {
123 1
		return result
124
	}
125
126 1
	return result + " " + trans().Ago
127
}
128
129
func optionIsEnabled(searchOption string) bool {
130 1
	for _, option := range globalOptions {
131 1
		if option == searchOption {
132 1
			return true
133
		}
134
	}
135
136 1
	return false
137
}
138
139
func enableOption(option string) {
140 1
	globalOptions = append(globalOptions, option)
141
}
142