Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
aca2d65b
Unverified
Commit
aca2d65b
authored
Oct 11, 2023
by
Michael Yang
Committed by
GitHub
Oct 11, 2023
Browse files
Merge pull request #757 from jmorganca/mxyng/format-time
cleanup format time
parents
274d5a5f
b5e08e33
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
17 additions
and
157 deletions
+17
-157
format/time.go
format/time.go
+11
-84
format/time_test.go
format/time_test.go
+6
-73
No files found.
format/time.go
View file @
aca2d65b
...
@@ -7,26 +7,14 @@ import (
...
@@ -7,26 +7,14 @@ import (
"time"
"time"
)
)
// HumanDuration returns a human-readable approximation of a duration
// humanDuration returns a human-readable approximation of a
// (eg. "About a minute", "4 hours ago", etc.).
// duration (eg. "About a minute", "4 hours ago", etc.).
// Modified version of github.com/docker/go-units.HumanDuration
func
humanDuration
(
d
time
.
Duration
)
string
{
func
HumanDuration
(
d
time
.
Duration
)
string
{
return
HumanDurationWithCase
(
d
,
true
)
}
// HumanDurationWithCase returns a human-readable approximation of a
// duration (eg. "About a minute", "4 hours ago", etc.). but allows
// you to specify whether the first word should be capitalized
// (eg. "About" vs. "about")
func
HumanDurationWithCase
(
d
time
.
Duration
,
useCaps
bool
)
string
{
seconds
:=
int
(
d
.
Seconds
())
seconds
:=
int
(
d
.
Seconds
())
switch
{
switch
{
case
seconds
<
1
:
case
seconds
<
1
:
if
useCaps
{
return
"Less than a second"
return
"Less than a second"
}
return
"less than a second"
case
seconds
==
1
:
case
seconds
==
1
:
return
"1 second"
return
"1 second"
case
seconds
<
60
:
case
seconds
<
60
:
...
@@ -36,10 +24,7 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
...
@@ -36,10 +24,7 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
minutes
:=
int
(
d
.
Minutes
())
minutes
:=
int
(
d
.
Minutes
())
switch
{
switch
{
case
minutes
==
1
:
case
minutes
==
1
:
if
useCaps
{
return
"About a minute"
return
"About a minute"
}
return
"about a minute"
case
minutes
<
60
:
case
minutes
<
60
:
return
fmt
.
Sprintf
(
"%d minutes"
,
minutes
)
return
fmt
.
Sprintf
(
"%d minutes"
,
minutes
)
}
}
...
@@ -47,10 +32,7 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
...
@@ -47,10 +32,7 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
hours
:=
int
(
math
.
Round
(
d
.
Hours
()))
hours
:=
int
(
math
.
Round
(
d
.
Hours
()))
switch
{
switch
{
case
hours
==
1
:
case
hours
==
1
:
if
useCaps
{
return
"About an hour"
return
"About an hour"
}
return
"about an hour"
case
hours
<
48
:
case
hours
<
48
:
return
fmt
.
Sprintf
(
"%d hours"
,
hours
)
return
fmt
.
Sprintf
(
"%d hours"
,
hours
)
case
hours
<
24
*
7
*
2
:
case
hours
<
24
*
7
*
2
:
...
@@ -65,77 +47,22 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
...
@@ -65,77 +47,22 @@ func HumanDurationWithCase(d time.Duration, useCaps bool) string {
}
}
func
HumanTime
(
t
time
.
Time
,
zeroValue
string
)
string
{
func
HumanTime
(
t
time
.
Time
,
zeroValue
string
)
string
{
return
humanTime
WithCase
(
t
,
zeroValue
,
true
)
return
humanTime
(
t
,
zeroValue
)
}
}
func
HumanTimeLower
(
t
time
.
Time
,
zeroValue
string
)
string
{
func
HumanTimeLower
(
t
time
.
Time
,
zeroValue
string
)
string
{
return
humanTime
WithCase
(
t
,
zeroValue
,
false
)
return
strings
.
ToLower
(
humanTime
(
t
,
zeroValue
)
)
}
}
func
humanTime
WithCase
(
t
time
.
Time
,
zeroValue
string
,
useCaps
bool
)
string
{
func
humanTime
(
t
time
.
Time
,
zeroValue
string
)
string
{
if
t
.
IsZero
()
{
if
t
.
IsZero
()
{
return
zeroValue
return
zeroValue
}
}
delta
:=
time
.
Since
(
t
)
delta
:=
time
.
Since
(
t
)
if
delta
<
0
{
if
delta
<
0
{
return
HumanDurationWithCase
(
-
delta
,
useCaps
)
+
" from now"
return
humanDuration
(
-
delta
)
+
" from now"
}
return
HumanDurationWithCase
(
delta
,
useCaps
)
+
" ago"
}
// ExcatDuration returns a human readable hours/minutes/seconds or milliseconds format of a duration
// the most precise level of duration is milliseconds
func
ExactDuration
(
d
time
.
Duration
)
string
{
if
d
.
Seconds
()
<
1
{
if
d
.
Milliseconds
()
==
1
{
return
fmt
.
Sprintf
(
"%d millisecond"
,
d
.
Milliseconds
())
}
return
fmt
.
Sprintf
(
"%d milliseconds"
,
d
.
Milliseconds
())
}
var
readableDur
strings
.
Builder
dur
:=
d
.
String
()
// split the default duration string format of 0h0m0s into something nicer to read
h
:=
strings
.
Split
(
dur
,
"h"
)
if
len
(
h
)
>
1
{
hours
:=
h
[
0
]
if
hours
==
"1"
{
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s hour "
,
hours
))
}
else
{
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s hours "
,
hours
))
}
dur
=
h
[
1
]
}
m
:=
strings
.
Split
(
dur
,
"m"
)
if
len
(
m
)
>
1
{
mins
:=
m
[
0
]
switch
mins
{
case
"0"
:
// skip
case
"1"
:
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s minute "
,
mins
))
default
:
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s minutes "
,
mins
))
}
dur
=
m
[
1
]
}
s
:=
strings
.
Split
(
dur
,
"s"
)
if
len
(
s
)
>
0
{
sec
:=
s
[
0
]
switch
sec
{
case
"0"
:
// skip
case
"1"
:
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s second "
,
sec
))
default
:
readableDur
.
WriteString
(
fmt
.
Sprintf
(
"%s seconds "
,
sec
))
}
}
}
return
strings
.
TrimSpace
(
readableDur
.
String
())
return
humanDuration
(
delta
)
+
" ago"
}
}
format/time_test.go
View file @
aca2d65b
...
@@ -11,92 +11,25 @@ func assertEqual(t *testing.T, a interface{}, b interface{}) {
...
@@ -11,92 +11,25 @@ func assertEqual(t *testing.T, a interface{}, b interface{}) {
}
}
}
}
func
TestHumanDuration
(
t
*
testing
.
T
)
{
day
:=
24
*
time
.
Hour
week
:=
7
*
day
month
:=
30
*
day
year
:=
365
*
day
assertEqual
(
t
,
"Less than a second"
,
HumanDuration
(
450
*
time
.
Millisecond
))
assertEqual
(
t
,
"Less than a second"
,
HumanDurationWithCase
(
450
*
time
.
Millisecond
,
true
))
assertEqual
(
t
,
"less than a second"
,
HumanDurationWithCase
(
450
*
time
.
Millisecond
,
false
))
assertEqual
(
t
,
"1 second"
,
HumanDuration
(
1
*
time
.
Second
))
assertEqual
(
t
,
"45 seconds"
,
HumanDuration
(
45
*
time
.
Second
))
assertEqual
(
t
,
"46 seconds"
,
HumanDuration
(
46
*
time
.
Second
))
assertEqual
(
t
,
"59 seconds"
,
HumanDuration
(
59
*
time
.
Second
))
assertEqual
(
t
,
"About a minute"
,
HumanDuration
(
60
*
time
.
Second
))
assertEqual
(
t
,
"About a minute"
,
HumanDurationWithCase
(
1
*
time
.
Minute
,
true
))
assertEqual
(
t
,
"about a minute"
,
HumanDurationWithCase
(
1
*
time
.
Minute
,
false
))
assertEqual
(
t
,
"3 minutes"
,
HumanDuration
(
3
*
time
.
Minute
))
assertEqual
(
t
,
"35 minutes"
,
HumanDuration
(
35
*
time
.
Minute
))
assertEqual
(
t
,
"35 minutes"
,
HumanDuration
(
35
*
time
.
Minute
+
40
*
time
.
Second
))
assertEqual
(
t
,
"45 minutes"
,
HumanDuration
(
45
*
time
.
Minute
))
assertEqual
(
t
,
"45 minutes"
,
HumanDuration
(
45
*
time
.
Minute
+
40
*
time
.
Second
))
assertEqual
(
t
,
"46 minutes"
,
HumanDuration
(
46
*
time
.
Minute
))
assertEqual
(
t
,
"59 minutes"
,
HumanDuration
(
59
*
time
.
Minute
))
assertEqual
(
t
,
"About an hour"
,
HumanDuration
(
1
*
time
.
Hour
))
assertEqual
(
t
,
"About an hour"
,
HumanDurationWithCase
(
1
*
time
.
Hour
+
29
*
time
.
Minute
,
true
))
assertEqual
(
t
,
"about an hour"
,
HumanDurationWithCase
(
1
*
time
.
Hour
+
29
*
time
.
Minute
,
false
))
assertEqual
(
t
,
"2 hours"
,
HumanDuration
(
1
*
time
.
Hour
+
31
*
time
.
Minute
))
assertEqual
(
t
,
"2 hours"
,
HumanDuration
(
1
*
time
.
Hour
+
59
*
time
.
Minute
))
assertEqual
(
t
,
"3 hours"
,
HumanDuration
(
3
*
time
.
Hour
))
assertEqual
(
t
,
"3 hours"
,
HumanDuration
(
3
*
time
.
Hour
+
29
*
time
.
Minute
))
assertEqual
(
t
,
"4 hours"
,
HumanDuration
(
3
*
time
.
Hour
+
31
*
time
.
Minute
))
assertEqual
(
t
,
"4 hours"
,
HumanDuration
(
3
*
time
.
Hour
+
59
*
time
.
Minute
))
assertEqual
(
t
,
"4 hours"
,
HumanDuration
(
3
*
time
.
Hour
+
60
*
time
.
Minute
))
assertEqual
(
t
,
"24 hours"
,
HumanDuration
(
24
*
time
.
Hour
))
assertEqual
(
t
,
"36 hours"
,
HumanDuration
(
1
*
day
+
12
*
time
.
Hour
))
assertEqual
(
t
,
"2 days"
,
HumanDuration
(
2
*
day
))
assertEqual
(
t
,
"7 days"
,
HumanDuration
(
7
*
day
))
assertEqual
(
t
,
"13 days"
,
HumanDuration
(
13
*
day
+
5
*
time
.
Hour
))
assertEqual
(
t
,
"2 weeks"
,
HumanDuration
(
2
*
week
))
assertEqual
(
t
,
"2 weeks"
,
HumanDuration
(
2
*
week
+
4
*
day
))
assertEqual
(
t
,
"3 weeks"
,
HumanDuration
(
3
*
week
))
assertEqual
(
t
,
"4 weeks"
,
HumanDuration
(
4
*
week
))
assertEqual
(
t
,
"4 weeks"
,
HumanDuration
(
4
*
week
+
3
*
day
))
assertEqual
(
t
,
"4 weeks"
,
HumanDuration
(
1
*
month
))
assertEqual
(
t
,
"6 weeks"
,
HumanDuration
(
1
*
month
+
2
*
week
))
assertEqual
(
t
,
"2 months"
,
HumanDuration
(
2
*
month
))
assertEqual
(
t
,
"2 months"
,
HumanDuration
(
2
*
month
+
2
*
week
))
assertEqual
(
t
,
"3 months"
,
HumanDuration
(
3
*
month
))
assertEqual
(
t
,
"3 months"
,
HumanDuration
(
3
*
month
+
1
*
week
))
assertEqual
(
t
,
"5 months"
,
HumanDuration
(
5
*
month
+
2
*
week
))
assertEqual
(
t
,
"13 months"
,
HumanDuration
(
13
*
month
))
assertEqual
(
t
,
"23 months"
,
HumanDuration
(
23
*
month
))
assertEqual
(
t
,
"24 months"
,
HumanDuration
(
24
*
month
))
assertEqual
(
t
,
"2 years"
,
HumanDuration
(
24
*
month
+
2
*
week
))
assertEqual
(
t
,
"3 years"
,
HumanDuration
(
3
*
year
+
2
*
month
))
}
func
TestHumanTime
(
t
*
testing
.
T
)
{
func
TestHumanTime
(
t
*
testing
.
T
)
{
now
:=
time
.
Now
()
now
:=
time
.
Now
()
t
.
Run
(
"zero value"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"zero value"
,
func
(
t
*
testing
.
T
)
{
assertEqual
(
t
,
HumanTime
(
time
.
Time
{},
"never"
),
"never"
)
assertEqual
(
t
,
HumanTime
(
time
.
Time
{},
"never"
),
"never"
)
})
})
t
.
Run
(
"time in the future"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"time in the future"
,
func
(
t
*
testing
.
T
)
{
v
:=
now
.
Add
(
48
*
time
.
Hour
)
v
:=
now
.
Add
(
48
*
time
.
Hour
)
assertEqual
(
t
,
HumanTime
(
v
,
""
),
"2 days from now"
)
assertEqual
(
t
,
HumanTime
(
v
,
""
),
"2 days from now"
)
})
})
t
.
Run
(
"time in the past"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"time in the past"
,
func
(
t
*
testing
.
T
)
{
v
:=
now
.
Add
(
-
48
*
time
.
Hour
)
v
:=
now
.
Add
(
-
48
*
time
.
Hour
)
assertEqual
(
t
,
HumanTime
(
v
,
""
),
"2 days ago"
)
assertEqual
(
t
,
HumanTime
(
v
,
""
),
"2 days ago"
)
})
})
}
func
TestExactDuration
(
t
*
testing
.
T
)
{
t
.
Run
(
"soon"
,
func
(
t
*
testing
.
T
)
{
assertEqual
(
t
,
"1 millisecond"
,
ExactDuration
(
1
*
time
.
Millisecond
))
v
:=
now
.
Add
(
800
*
time
.
Millisecond
)
assertEqual
(
t
,
"10 milliseconds"
,
ExactDuration
(
10
*
time
.
Millisecond
))
assertEqual
(
t
,
HumanTime
(
v
,
""
),
"Less than a second from now"
)
assertEqual
(
t
,
"1 second"
,
ExactDuration
(
1
*
time
.
Second
))
})
assertEqual
(
t
,
"10 seconds"
,
ExactDuration
(
10
*
time
.
Second
))
assertEqual
(
t
,
"1 minute"
,
ExactDuration
(
1
*
time
.
Minute
))
assertEqual
(
t
,
"10 minutes"
,
ExactDuration
(
10
*
time
.
Minute
))
assertEqual
(
t
,
"1 hour"
,
ExactDuration
(
1
*
time
.
Hour
))
assertEqual
(
t
,
"10 hours"
,
ExactDuration
(
10
*
time
.
Hour
))
assertEqual
(
t
,
"1 hour 1 second"
,
ExactDuration
(
1
*
time
.
Hour
+
1
*
time
.
Second
))
assertEqual
(
t
,
"1 hour 10 seconds"
,
ExactDuration
(
1
*
time
.
Hour
+
10
*
time
.
Second
))
assertEqual
(
t
,
"1 hour 1 minute"
,
ExactDuration
(
1
*
time
.
Hour
+
1
*
time
.
Minute
))
assertEqual
(
t
,
"1 hour 10 minutes"
,
ExactDuration
(
1
*
time
.
Hour
+
10
*
time
.
Minute
))
assertEqual
(
t
,
"1 hour 1 minute 1 second"
,
ExactDuration
(
1
*
time
.
Hour
+
1
*
time
.
Minute
+
1
*
time
.
Second
))
assertEqual
(
t
,
"10 hours 10 minutes 10 seconds"
,
ExactDuration
(
10
*
time
.
Hour
+
10
*
time
.
Minute
+
10
*
time
.
Second
))
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment