1package sprig
2
3import (
4	"strconv"
5	"time"
6)
7
8// Given a format and a date, format the date string.
9//
10// Date can be a `time.Time` or an `int, int32, int64`.
11// In the later case, it is treated as seconds since UNIX
12// epoch.
13func date(fmt string, date interface{}) string {
14	return dateInZone(fmt, date, "Local")
15}
16
17func htmlDate(date interface{}) string {
18	return dateInZone("2006-01-02", date, "Local")
19}
20
21func htmlDateInZone(date interface{}, zone string) string {
22	return dateInZone("2006-01-02", date, zone)
23}
24
25func dateInZone(fmt string, date interface{}, zone string) string {
26	var t time.Time
27	switch date := date.(type) {
28	default:
29		t = time.Now()
30	case time.Time:
31		t = date
32	case *time.Time:
33		t = *date
34	case int64:
35		t = time.Unix(date, 0)
36	case int:
37		t = time.Unix(int64(date), 0)
38	case int32:
39		t = time.Unix(int64(date), 0)
40	}
41
42	loc, err := time.LoadLocation(zone)
43	if err != nil {
44		loc, _ = time.LoadLocation("UTC")
45	}
46
47	return t.In(loc).Format(fmt)
48}
49
50func dateModify(fmt string, date time.Time) time.Time {
51	d, err := time.ParseDuration(fmt)
52	if err != nil {
53		return date
54	}
55	return date.Add(d)
56}
57
58func dateAgo(date interface{}) string {
59	var t time.Time
60
61	switch date := date.(type) {
62	default:
63		t = time.Now()
64	case time.Time:
65		t = date
66	case int64:
67		t = time.Unix(date, 0)
68	case int:
69		t = time.Unix(int64(date), 0)
70	}
71	// Drop resolution to seconds
72	duration := time.Since(t).Round(time.Second)
73	return duration.String()
74}
75
76func toDate(fmt, str string) time.Time {
77	t, _ := time.ParseInLocation(fmt, str, time.Local)
78	return t
79}
80
81func unixEpoch(date time.Time) string {
82	return strconv.FormatInt(date.Unix(), 10)
83}
84