-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathtimeago.go
152 lines (136 loc) · 4.08 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
// Package time provides a set of functions to return how much
// time has been passed between two dates.
package timeago
import (
"time"
"fmt"
"math"
"errors"
)
type DateAgoValues int
const (
SecondsAgo DateAgoValues = iota
MinutesAgo
HoursAgo
DaysAgo
WeeksAgo
MonthsAgo
YearsAgo
)
// TimeAgoFromNowWithTime takes a specific end Time value
// and the current Time to return how much has been passed
// between them.
func TimeAgoFromNowWithTime(end time.Time) (string, error) {
return TimeAgoWithTime(time.Now(), end)
}
// TimeAgoFromNowWithTime takes a specific layout as time
// format to parse the time string on end paramter to return
// how much time has been passed between the current time and
// the string representation of the time provided by user.
func TimeAgoFromNowWithString(layout, end string) (string, error) {
t, e := time.Parse(layout, end)
if e == nil {
return TimeAgoWithTime(time.Now(), t)
} else {
err := errors.New("Invalid format")
return "", err
}
}
// TimeAgoWithTime takes a specific start/end Time values
// and calculate how much time has been passed between them.
func TimeAgoWithTime(start, end time.Time) (string, error) {
duration := start.Sub(end)
return stringForDuration(duration), nil
}
// TimeAgoWithString takes a specific layout as time
// format to parse the time string on start/end parameter to return
// how much time has been passed between them.
func TimeAgoWithString(layout, start, end string) (string, error) {
timeStart, e := time.Parse(layout, start)
if e != nil {
err := errors.New("Invalid start time format")
return "", err
}
timeEnd, e := time.Parse(layout, end)
if e != nil {
err := errors.New("Invalid end time format")
return "", err
}
duration := timeStart.Sub(timeEnd)
return stringForDuration(duration), nil
}
func stringForDuration(duration time.Duration) string {
if duration.Hours() < 24 {
if duration.Hours() >= 1 {
return localizedStringFor(HoursAgo, int(round(duration.Hours())));
} else if duration.Minutes() >= 1 {
return localizedStringFor(MinutesAgo, int(round(duration.Minutes())));
} else {
return localizedStringFor(SecondsAgo, int(round(duration.Seconds())));
}
} else {
if duration.Hours() >= 8760 {
years := duration.Hours() / 8760
return localizedStringFor(YearsAgo, int(years));
} else if duration.Hours() >= 730 {
months := duration.Hours() / 730
return localizedStringFor(MonthsAgo, int(months));
} else if duration.Hours() >= 168 {
weeks := duration.Hours() / 168
return localizedStringFor(WeeksAgo, int(weeks));
} else {
days := duration.Hours() / 24
return localizedStringFor(DaysAgo, int(days));
}
}
}
func round(f float64) float64 {
return math.Floor(f + .5)
}
func localizedStringFor(valueType DateAgoValues, value int) string {
switch valueType {
case YearsAgo:
if value >= 2 {
return fmt.Sprintf("%d years ago", value);
} else {
return "Last year";
}
case MonthsAgo:
if value >= 2 {
return fmt.Sprintf("%d months ago", value);
} else {
return "Last month";
}
case WeeksAgo:
if value >= 2 {
return fmt.Sprintf("%d weeks ago", value);
} else {
return "Last week";
}
case DaysAgo:
if value >= 2 {
return fmt.Sprintf("%d days ago", value);
} else {
return "Yesterday";
}
case HoursAgo:
if value >= 2 {
return fmt.Sprintf("%d hours ago", value);
} else {
return "An hour ago";
}
case MinutesAgo:
if value >= 2 {
return fmt.Sprintf("%d minutes ago", value);
} else {
return "A minute ago";
}
case SecondsAgo:
if value >= 2 {
return fmt.Sprintf("%d seconds ago", value);
} else {
return "Just now";
}
}
return "";
}