EasyDarwin/vendor/github.com/lestrrat-go/strftime/writer.go

169 lines
2.7 KiB
Go

package strftime
import (
"strconv"
"strings"
"time"
)
type appender interface {
Append([]byte, time.Time) []byte
}
type appenderList []appender
// does the time.Format thing
type timefmtw struct {
s string
}
func timefmt(s string) *timefmtw {
return &timefmtw{s: s}
}
func (v timefmtw) Append(b []byte, t time.Time) []byte {
return t.AppendFormat(b, v.s)
}
func (v timefmtw) str() string {
return v.s
}
func (v timefmtw) canCombine() bool {
return true
}
func (v timefmtw) combine(w combiner) appender {
return timefmt(v.s + w.str())
}
type verbatimw struct {
s string
}
func verbatim(s string) *verbatimw {
return &verbatimw{s: s}
}
func (v verbatimw) Append(b []byte, _ time.Time) []byte {
return append(b, v.s...)
}
func (v verbatimw) canCombine() bool {
return canCombine(v.s)
}
func (v verbatimw) combine(w combiner) appender {
if _, ok := w.(*timefmtw); ok {
return timefmt(v.s + w.str())
}
return verbatim(v.s + w.str())
}
func (v verbatimw) str() string {
return v.s
}
// These words below, as well as any decimal character
var combineExclusion = []string{
"Mon",
"Monday",
"Jan",
"January",
"MST",
"PM",
}
func canCombine(s string) bool {
if strings.ContainsAny(s, "0123456789") {
return false
}
for _, word := range combineExclusion {
if strings.Contains(s, word) {
return false
}
}
return true
}
type combiner interface {
canCombine() bool
combine(combiner) appender
str() string
}
type century struct{}
func (v century) Append(b []byte, t time.Time) []byte {
n := t.Year() / 100
if n < 10 {
b = append(b, '0')
}
return append(b, strconv.Itoa(n)...)
}
type weekday int
func (v weekday) Append(b []byte, t time.Time) []byte {
n := int(t.Weekday())
if n < int(v) {
n += 7
}
return append(b, byte(n+48))
}
type weeknumberOffset int
func (v weeknumberOffset) Append(b []byte, t time.Time) []byte {
yd := t.YearDay()
offset := int(t.Weekday()) - int(v)
if offset < 0 {
offset += 7
}
if yd < offset {
return append(b, '0', '0')
}
n := ((yd - offset) / 7) + 1
if n < 10 {
b = append(b, '0')
}
return append(b, strconv.Itoa(n)...)
}
type weeknumber struct{}
func (v weeknumber) Append(b []byte, t time.Time) []byte {
_, n := t.ISOWeek()
if n < 10 {
b = append(b, '0')
}
return append(b, strconv.Itoa(n)...)
}
type dayofyear struct{}
func (v dayofyear) Append(b []byte, t time.Time) []byte {
n := t.YearDay()
if n < 10 {
b = append(b, '0', '0')
} else if n < 100 {
b = append(b, '0')
}
return append(b, strconv.Itoa(n)...)
}
type hourwblank bool
func (v hourwblank) Append(b []byte, t time.Time) []byte {
h := t.Hour()
if bool(v) && h > 12 {
h = h - 12
}
if h < 10 {
b = append(b, ' ')
}
return append(b, strconv.Itoa(h)...)
}