| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- package sprig
- import (
- "math"
- "strconv"
- "time"
- )
- // date formats a date according to the provided format string.
- //
- // Parameters:
- // - fmt: A Go time format string (e.g., "2006-01-02 15:04:05")
- // - date: Can be a time.Time, *time.Time, or int/int32/int64 (seconds since UNIX epoch)
- //
- // If date is not one of the recognized types, the current time is used.
- //
- // Example usage in templates: {{ now | date "2006-01-02" }}
- func date(fmt string, date any) string {
- return dateInZone(fmt, date, "Local")
- }
- // htmlDate formats a date in HTML5 date format (YYYY-MM-DD).
- //
- // Parameters:
- // - date: Can be a time.Time, *time.Time, or int/int32/int64 (seconds since UNIX epoch)
- //
- // If date is not one of the recognized types, the current time is used.
- //
- // Example usage in templates: {{ now | htmlDate }}
- func htmlDate(date any) string {
- return dateInZone("2006-01-02", date, "Local")
- }
- // htmlDateInZone formats a date in HTML5 date format (YYYY-MM-DD) in the specified timezone.
- //
- // Parameters:
- // - date: Can be a time.Time, *time.Time, or int/int32/int64 (seconds since UNIX epoch)
- // - zone: Timezone name (e.g., "UTC", "America/New_York")
- //
- // If date is not one of the recognized types, the current time is used.
- // If the timezone is invalid, UTC is used.
- //
- // Example usage in templates: {{ now | htmlDateInZone "UTC" }}
- func htmlDateInZone(date any, zone string) string {
- return dateInZone("2006-01-02", date, zone)
- }
- // dateInZone formats a date according to the provided format string in the specified timezone.
- //
- // Parameters:
- // - fmt: A Go time format string (e.g., "2006-01-02 15:04:05")
- // - date: Can be a time.Time, *time.Time, or int/int32/int64 (seconds since UNIX epoch)
- // - zone: Timezone name (e.g., "UTC", "America/New_York")
- //
- // If date is not one of the recognized types, the current time is used.
- // If the timezone is invalid, UTC is used.
- //
- // Example usage in templates: {{ now | dateInZone "2006-01-02 15:04:05" "UTC" }}
- func dateInZone(fmt string, date any, zone string) string {
- var t time.Time
- switch date := date.(type) {
- default:
- t = time.Now()
- case time.Time:
- t = date
- case *time.Time:
- t = *date
- case int64:
- t = time.Unix(date, 0)
- case int:
- t = time.Unix(int64(date), 0)
- case int32:
- t = time.Unix(int64(date), 0)
- }
- loc, err := time.LoadLocation(zone)
- if err != nil {
- loc, _ = time.LoadLocation("UTC")
- }
- return t.In(loc).Format(fmt)
- }
- // dateModify modifies a date by adding a duration and returns the resulting time.
- //
- // Parameters:
- // - fmt: A duration string (e.g., "24h", "-12h30m", "1h15m30s")
- // - date: The time.Time to modify
- //
- // If the duration string is invalid, the original date is returned.
- //
- // Example usage in templates: {{ now | dateModify "-24h" }}
- func dateModify(fmt string, date time.Time) time.Time {
- d, err := time.ParseDuration(fmt)
- if err != nil {
- return date
- }
- return date.Add(d)
- }
- // mustDateModify modifies a date by adding a duration and returns the resulting time or an error.
- //
- // Parameters:
- // - fmt: A duration string (e.g., "24h", "-12h30m", "1h15m30s")
- // - date: The time.Time to modify
- //
- // Unlike dateModify, this function returns an error if the duration string is invalid.
- //
- // Example usage in templates: {{ now | mustDateModify "24h" }}
- func mustDateModify(fmt string, date time.Time) (time.Time, error) {
- d, err := time.ParseDuration(fmt)
- if err != nil {
- return time.Time{}, err
- }
- return date.Add(d), nil
- }
- // dateAgo returns a string representing the time elapsed since the given date.
- //
- // Parameters:
- // - date: Can be a time.Time, int, or int64 (seconds since UNIX epoch)
- //
- // If date is not one of the recognized types, the current time is used.
- //
- // Example usage in templates: {{ "2023-01-01" | toDate "2006-01-02" | dateAgo }}
- func dateAgo(date any) string {
- var t time.Time
- switch date := date.(type) {
- default:
- t = time.Now()
- case time.Time:
- t = date
- case int64:
- t = time.Unix(date, 0)
- case int:
- t = time.Unix(int64(date), 0)
- }
- return time.Since(t).Round(time.Second).String()
- }
- // duration converts seconds to a duration string.
- //
- // Parameters:
- // - sec: Can be a string (parsed as int64), or int64 representing seconds
- //
- // Example usage in templates: {{ 3600 | duration }} -> "1h0m0s"
- func duration(sec any) string {
- var n int64
- switch value := sec.(type) {
- default:
- n = 0
- case string:
- n, _ = strconv.ParseInt(value, 10, 64)
- case int64:
- n = value
- }
- return (time.Duration(n) * time.Second).String()
- }
- // durationRound formats a duration in a human-readable rounded format.
- //
- // Parameters:
- // - duration: Can be a string (parsed as duration), int64 (nanoseconds),
- // or time.Time (time since that moment)
- //
- // Returns a string with the largest appropriate unit (y, mo, d, h, m, s).
- //
- // Example usage in templates: {{ 3600 | duration | durationRound }} -> "1h"
- func durationRound(duration any) string {
- var d time.Duration
- switch duration := duration.(type) {
- default:
- d = 0
- case string:
- d, _ = time.ParseDuration(duration)
- case int64:
- d = time.Duration(duration)
- case time.Time:
- d = time.Since(duration)
- }
- u := uint64(math.Abs(float64(d)))
- var (
- year = uint64(time.Hour) * 24 * 365
- month = uint64(time.Hour) * 24 * 30
- day = uint64(time.Hour) * 24
- hour = uint64(time.Hour)
- minute = uint64(time.Minute)
- second = uint64(time.Second)
- )
- switch {
- case u > year:
- return strconv.FormatUint(u/year, 10) + "y"
- case u > month:
- return strconv.FormatUint(u/month, 10) + "mo"
- case u > day:
- return strconv.FormatUint(u/day, 10) + "d"
- case u > hour:
- return strconv.FormatUint(u/hour, 10) + "h"
- case u > minute:
- return strconv.FormatUint(u/minute, 10) + "m"
- case u > second:
- return strconv.FormatUint(u/second, 10) + "s"
- }
- return "0s"
- }
- // toDate parses a string into a time.Time using the specified format.
- //
- // Parameters:
- // - fmt: A Go time format string (e.g., "2006-01-02")
- // - str: The date string to parse
- //
- // If parsing fails, returns a zero time.Time.
- //
- // Example usage in templates: {{ "2023-01-01" | toDate "2006-01-02" }}
- func toDate(fmt, str string) time.Time {
- t, _ := time.ParseInLocation(fmt, str, time.Local)
- return t
- }
- // mustToDate parses a string into a time.Time using the specified format or returns an error.
- //
- // Parameters:
- // - fmt: A Go time format string (e.g., "2006-01-02")
- // - str: The date string to parse
- //
- // Unlike toDate, this function returns an error if parsing fails.
- //
- // Example usage in templates: {{ mustToDate "2006-01-02" "2023-01-01" }}
- func mustToDate(fmt, str string) (time.Time, error) {
- return time.ParseInLocation(fmt, str, time.Local)
- }
- // unixEpoch returns the Unix timestamp (seconds since January 1, 1970 UTC) for the given time.
- //
- // Parameters:
- // - date: A time.Time value
- //
- // Example usage in templates: {{ now | unixEpoch }}
- func unixEpoch(date time.Time) string {
- return strconv.FormatInt(date.Unix(), 10)
- }
|