ADDED: * math, time functions to tplx/sprigx FIXED: * logging not initializing properly on some BSDs
140 lines
2.5 KiB
Go
140 lines
2.5 KiB
Go
package sprigx
|
|
|
|
import (
|
|
`errors`
|
|
`strconv`
|
|
`strings`
|
|
`time`
|
|
)
|
|
|
|
/*
|
|
tmFmt formats time t using format string fstr.
|
|
|
|
While one certainly can do the same via e.g.
|
|
|
|
{{- $t := tmNow -}}
|
|
{{ $t.Format $fstr }}
|
|
|
|
This takes a time.Time as the second (and last) parameter,
|
|
allowing it to work in pipelines.
|
|
*/
|
|
func tmFmt(fstr string, t time.Time) (out string) {
|
|
|
|
out = t.Format(fstr)
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
tmParseMonth attempts to first try tmParseMonthInt
|
|
and then tries tmParseMonthStr if v is not "numeric".
|
|
*/
|
|
func tmParseMonth(v any) (mon time.Month, err error) {
|
|
|
|
var s string
|
|
|
|
if mon, err = tmParseMonthInt(v); err != nil {
|
|
if errors.Is(err, strconv.ErrSyntax) {
|
|
// NaN
|
|
err = nil
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
|
|
// If it gets here, it's a non-numeric string.
|
|
if s, err = toString(v); err != nil {
|
|
return
|
|
}
|
|
if mon, err = tmParseMonthStr(s); err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
tmParseMonthInt parses a number representation of month n to a time.Month.
|
|
n may be any numeric type or a string representation of a number
|
|
(or a custom type derived from those).
|
|
|
|
A negative integer (or float, etc.) will be converted to a positive one (e.g. -6 => 6 => time.June).
|
|
|
|
floats are rounded to the nearest integer.
|
|
|
|
The integer should map directly to the month constants in the time module:
|
|
|
|
* 1: January
|
|
* 2: February
|
|
* 3: March
|
|
* 4: April
|
|
* 5: May
|
|
* 6: June
|
|
* 7: July
|
|
* 8: August
|
|
* 9: September
|
|
* 10: October
|
|
* 11: November
|
|
* 12: December
|
|
|
|
If n resolves to 0, mon will be the current month (as determined by time.Now).
|
|
|
|
If n resolves to > 12, err will be ErrBadMonth.
|
|
*/
|
|
func tmParseMonthInt(n any) (mon time.Month, err error) {
|
|
|
|
var i int
|
|
|
|
if i, _, err = toPosInt(n); err != nil {
|
|
return
|
|
}
|
|
|
|
if i == 0 {
|
|
mon = time.Now().Month()
|
|
return
|
|
}
|
|
|
|
if i > 12 {
|
|
err = ErrBadMonth
|
|
return
|
|
}
|
|
|
|
mon = time.Month(i)
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
tmParseMonthStr parses a string representation of month s to a time.Month.
|
|
|
|
It normalizes s to lowercase and only uses the first 3 characters
|
|
(the minimum length needed to determine month name
|
|
uniqueness - "June" vs. "July", "March" vs. "May").
|
|
|
|
An empty (or whitespace-only) string will use the current month (as determined by time.Now).
|
|
*/
|
|
func tmParseMonthStr(s string) (mon time.Month, err error) {
|
|
|
|
var i int
|
|
var m time.Month
|
|
|
|
if strings.TrimSpace(s) == "" {
|
|
mon = time.Now().Month()
|
|
return
|
|
}
|
|
|
|
s = strings.ToLower(strings.TrimSpace(s))[0:3]
|
|
|
|
for i = range 12 {
|
|
m = time.Month(i + 1)
|
|
if strings.ToLower(m.String())[0:3] == s {
|
|
mon = m
|
|
return
|
|
}
|
|
}
|
|
|
|
err = ErrBadMonth
|
|
|
|
return
|
|
}
|