diff --git a/funcmap.go b/funcmap.go index 85e7999..01710cb 100644 --- a/funcmap.go +++ b/funcmap.go @@ -46,6 +46,7 @@ var Funcs = map[string]interface{}{ "stat": Stat, "title": ToTitle, "time": Time, + "timeAgo": TimeAgo, "trimLeft": TrimLeft, "trimRight": TrimRight, "trimPrefix": TrimPrefix, @@ -92,6 +93,7 @@ var SafeFuncs = map[string]interface{}{ "splitn": SplitN, "title": ToTitle, "time": Time, + "timeAgo": TimeAgo, "trimLeft": TrimLeft, "trimRight": TrimRight, "trimPrefix": TrimPrefix, diff --git a/time.go b/time.go index 93ce9f0..1e79df0 100644 --- a/time.go +++ b/time.go @@ -4,7 +4,10 @@ package funcmap -import "time" +import ( + "fmt" + "time" +) // Time converts the textual representation of the datetime // string into a time.Time interface. @@ -44,3 +47,43 @@ func TimeFormat(layout string, v interface{}) (string, error) { func Now() time.Time { return time.Now() } + +// TimeAgo returns the relative time. +func TimeAgo(v interface{}) (string, error) { + t, err := toTimeE(v) + if err != nil { + return "", err + } + + now := time.Now() + diff := now.Sub(t) + + switch { + case diff < time.Minute: + secs := int(diff.Seconds()) + if secs <= 1 { + return "1s ago", nil + } + return fmt.Sprintf("%ds ago", secs), nil + + case diff < time.Hour: + mins := int(diff.Minutes()) + return fmt.Sprintf("%dm ago", mins), nil + + case diff < 24*time.Hour: + hours := int(diff.Hours()) + return fmt.Sprintf("%dh ago", hours), nil + + case diff < 30*24*time.Hour: + days := int(diff.Hours() / 24) + return fmt.Sprintf("%dd ago", days), nil + + case diff < 365*24*time.Hour: + months := int(diff.Hours() / (24 * 30)) + return fmt.Sprintf("%dmo ago", months), nil + + default: + years := int(diff.Hours() / (24 * 365)) + return fmt.Sprintf("%dy ago", years), nil + } +}