Passed
Push — master ( 263cb0...39e168 )
by Serhii
03:24 queued 01:58
created

timeago.getLastNumber   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
package timeago
2
3
import (
4
	"fmt"
5
	"log"
6
	"math"
7
	"path"
8
	"runtime"
9
	"strconv"
10
	"strings"
11
	"time"
12
13
	"github.com/SerhiiCho/timeago/models"
14
	"github.com/SerhiiCho/timeago/utils"
15
)
16
17
var cachedJsonResults = map[string]models.Lang{}
18
19
// Take coverts given datetime into `x time ago` format.
20
// For displaying `Online` word if date interval within
21
// 60 seconds, add `|online` flag to the datetime string.
22
// Format must be [year-month-day hours:minutes:seconds}
23
func Take(datetime string) string {
24
	option, hasOption := getOption(&datetime)
25
26
	loc, _ := time.LoadLocation(location)
27
	parsedTime, _ := time.ParseInLocation("2006-01-02 15:04:05", datetime, loc)
28
	seconds := int(time.Now().In(loc).Sub(parsedTime).Seconds())
29
30
	switch {
31
	case seconds < 60 && option == "online":
32
		return trans().Online
33
	case seconds < 0:
34
		return getWords("seconds", 0)
35
	}
36
37
	return calculateTheResult(seconds, hasOption, option)
38
}
39
40
func calculateTheResult(seconds int, hasOption bool, option string) string {
41
	minutes, hours, days, weeks, months, years := getTimeCalculations(float64(seconds))
42
43
	switch {
44
	case hasOption && option == "online" && seconds < 60:
45
		return trans().Online
46
	case seconds < 60:
47
		return getWords("seconds", seconds)
48
	case minutes < 60:
49
		return getWords("minutes", minutes)
50
	case hours < 24:
51
		return getWords("hours", hours)
52
	case days < 7:
53
		return getWords("days", days)
54
	case weeks < 4:
55
		return getWords("weeks", weeks)
56
	case months < 12:
57
		if months == 0 {
58
			months = 1
59
		}
60
61
		return getWords("months", months)
62
	}
63
64
	return getWords("years", years)
65
}
66
67
func getTimeCalculations(seconds float64) (int, int, int, int, int, int) {
68
	minutes := math.Round(seconds / 60)
69
	hours := math.Round(seconds / 3600)
70
	days := math.Round(seconds / 86400)
71
	weeks := math.Round(seconds / 604800)
72
	months := math.Round(seconds / 2629440)
73
	years := math.Round(seconds / 31553280)
74
75
	return int(minutes), int(hours), int(days), int(weeks), int(months), int(years)
76
}
77
78
// get the last number of a given integer
79
func getLastNumber(num int) int {
80 1
	numStr := strconv.Itoa(num)
81 1
	result, _ := strconv.Atoi(numStr[len(numStr)-1:])
82
83 1
	return result
84
}
85
86
// getWords decides rather the word must be singular or plural,
87
// and depending on the result it adds the correct word after
88
// the time number
89
func getWords(timeKind string, num int) string {
90 1
	form := getLanguageForm(num)
91 1
	time := getTimeTranslations()
92
93 1
	translation := time[timeKind][form]
94
95 1
	return strconv.Itoa(num) + " " + translation + " " + trans().Ago
96
}
97
98
// getOption check if datetime has option with time,
99
// if yes, it will return this option and remove it
100
// from datetime
101
func getOption(datetime *string) (string, bool) {
102 1
	date := *datetime
103 1
	spittedDateString := strings.Split(date, "|")
104
105 1
	if len(spittedDateString) > 1 {
106 1
		*datetime = spittedDateString[0]
107 1
		return spittedDateString[1], true
108
	}
109
110 1
	return "", false
111
}
112
113
func trans() models.Lang {
114 1
	_, filename, _, ok := runtime.Caller(0)
115
116 1
	if !ok {
117
		panic("No caller information")
118
	}
119
120 1
	rootPath := path.Dir(filename)
121
122 1
	filePath := fmt.Sprintf(rootPath+"/langs/%s.json", language)
123
124 1
	if cachedResult, ok := cachedJsonResults[filePath]; ok {
125 1
		return cachedResult
126
	}
127
128 1
	thereIsFile, err := utils.FileExists(filePath)
129
130 1
	if !thereIsFile {
131
		log.Fatalf("File with the path: %s, doesn't exist", filePath)
132
	}
133
134 1
	if err != nil {
135
		log.Fatalf("Error while trying to read file %s. Error: %v", filePath, err)
136
	}
137
138 1
	parseResult := parseNeededFile(filePath)
139
140 1
	cachedJsonResults[filePath] = parseResult
141
142 1
	return parseResult
143
}
144