-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeString.go
133 lines (117 loc) · 3.09 KB
/
timeString.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
package tt
import (
"fmt"
"regexp"
"strconv"
"time"
)
const TimeFormat = "2006-01-02 15:04"
var datePattern = regexp.MustCompile(`((\d{4})[-/.](\d{1,2})[-/.](\d{1,2}))?([T ])?(\d{1,2}):(\d{1,2}):?(\d{1,2})?`)
// ParseTime will take in a string that contains a time in some format and try
// to guess the missing parts. Currently, the following cases are supported:
// - 15:04
// - 15:04:05
// - 2006/01/02 15:04
// - 2006/01/02 15:04:05
// valid date separators: dash, dot, slash
// valid time separators: colon
// valid separators between date and time: space, upper-case t
//
// more general information will be taken from time.Now() (e.g. day or year) and
// more specific information (e.g. seconds) will be set to zero.
func ParseTime(in string) (time.Time, error) {
// if we can parse as RFC3339 we just return it
t, err := time.Parse(time.RFC3339, in)
if err == nil {
return t, nil
}
matches := datePattern.FindSubmatch([]byte(in))
if len(matches) == 0 {
return time.Time{}, fmt.Errorf("timestamp is not RFC3339 compliant and does not match custom format")
}
now := time.Now()
var year, month, day, hour, min, sec int
yearStr := string(matches[2])
if yearStr != "" {
year, err = strconv.Atoi(yearStr)
if err != nil {
return time.Time{}, err
}
} else {
year = now.Year()
}
monthStr := string(matches[3])
if monthStr != "" {
month, err = strconv.Atoi(monthStr)
if err != nil {
return time.Time{}, err
}
} else {
month = int(now.Month())
}
dayStr := string(matches[4])
if dayStr != "" {
day, err = strconv.Atoi(dayStr)
if err != nil {
return time.Time{}, err
}
} else {
day = now.Day()
}
hour, err = strconv.Atoi(string(matches[6]))
if err != nil {
return time.Time{}, err
}
min, err = strconv.Atoi(string(matches[7]))
if err != nil {
return time.Time{}, err
}
secStr := string(matches[8])
if secStr != "" {
sec, err = strconv.Atoi(secStr)
if err != nil {
return time.Time{}, err
}
} else {
sec = 0
}
return time.Date(year, time.Month(month), day, hour, min, sec, 0, time.Local), nil
}
func ParseDate(in string) (time.Time, error) {
now := time.Now()
switch in {
case "today":
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local), nil
case "yesterday":
return time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, time.Local), nil
default:
return time.Parse(DateFormat, in)
}
}
// FormatDuration formats a duration in the given precision specified by the
// config.
func FormatDuration(d time.Duration) string {
return FormatDurationCustom(d, GetConfig().GetPrecision())
}
func FormatDurationCustom(d time.Duration, precision time.Duration) string {
h := d / time.Hour
m := (d - (h * time.Hour)) / time.Minute
s := (d - (h * time.Hour) - (m * time.Minute)) / time.Second
sign := ""
if d < 0 {
sign = "-"
h *= -1
m *= -1
s *= -1
}
switch precision {
case time.Second:
return fmt.Sprintf("%s%02dh%02dm%02ds", sign, h, m, s)
case time.Minute:
return fmt.Sprintf("%s%02dh%02dm", sign, h, m)
case time.Hour:
return fmt.Sprintf("%s%02dh", sign, h)
default:
return "unknown precision"
}
}