Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions pkg/utils/date.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,54 @@ import (

func UnixToTimeAgo(timestamp int64) string {
now := time.Now().Unix()
delta := float64(now - timestamp)
// we go seconds, minutes, hours, days, weeks, months, years
conversions := []float64{60, 60, 24, 7, 4.34524, 12}
labels := []string{"s", "m", "h", "d", "w", "m", "y"}
for i, conversion := range conversions {
if delta < conversion {
return fmt.Sprintf("%d%s", int(delta), labels[i])
return formatSecondsAgo(now - timestamp)
}

const (
SECONDS_IN_SECOND = 1
SECONDS_IN_MINUTE = 60
SECONDS_IN_HOUR = 3600
SECONDS_IN_DAY = 86400
SECONDS_IN_WEEK = 604800
SECONDS_IN_YEAR = 31536000
SECONDS_IN_MONTH = SECONDS_IN_YEAR / 12
)

type period struct {
label string
secondsInPeriod int64
}

var periods = []period{
{"s", SECONDS_IN_SECOND},
{"m", SECONDS_IN_MINUTE},
{"h", SECONDS_IN_HOUR},
{"d", SECONDS_IN_DAY},
{"w", SECONDS_IN_WEEK},
// we're using 'm' for both minutes and months which is ambiguous but
// disambiguating with another character feels like overkill.
{"m", SECONDS_IN_MONTH},
{"y", SECONDS_IN_YEAR},
}

func formatSecondsAgo(secondsAgo int64) string {
for i, period := range periods {
if i == 0 {
continue
}

if secondsAgo < period.secondsInPeriod {
return fmt.Sprintf("%d%s",
secondsAgo/periods[i-1].secondsInPeriod,
periods[i-1].label,
)
}
delta /= conversion
}
return fmt.Sprintf("%dy", int(delta))

return fmt.Sprintf("%d%s",
secondsAgo/periods[len(periods)-1].secondsInPeriod,
periods[len(periods)-1].label,
)
}

// formats the date in a smart way, if the date is today, it will show the time, otherwise it will show the date
Expand Down
97 changes: 97 additions & 0 deletions pkg/utils/date_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package utils

import (
"testing"
)

func TestFormatSecondsAgo(t *testing.T) {
tests := []struct {
name string
args int64
want string
}{
{
name: "zero",
args: 0,
want: "0s",
},
{
name: "one second",
args: 1,
want: "1s",
},
{
name: "almost a minute",
args: 59,
want: "59s",
},
{
name: "one minute",
args: 60,
want: "1m",
},
{
name: "one minute and one second",
args: 61,
want: "1m",
},
{
name: "almost one hour",
args: 3599,
want: "59m",
},
{
name: "one hour",
args: 3600,
want: "1h",
},
{
name: "almost one day",
args: 86399,
want: "23h",
},
{
name: "one day",
args: 86400,
want: "1d",
},
{
name: "almost a week",
args: 604799,
want: "6d",
},
{
name: "one week",
args: 604800,
want: "1w",
},
{
name: "six months",
args: SECONDS_IN_YEAR / 2,
want: "6m",
},
{
name: "almost one year",
args: 31535999,
want: "11m",
},
{
name: "one year",
args: SECONDS_IN_YEAR,
want: "1y",
},
{
name: "50 years",
args: SECONDS_IN_YEAR * 50,
want: "50y",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := formatSecondsAgo(tt.args); got != tt.want {
t.Errorf("formatSecondsAgo(%d) = %v, want %v", tt.args, got, tt.want)
}
})
}
}