github.com/gdubicki/ets@v0.2.3-0.20240420195337-e89d6a2fdbda/timestamper.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "log" 6 "math" 7 "strconv" 8 "time" 9 10 "github.com/lestrrat-go/strftime" 11 ) 12 13 type TimestampMode int 14 15 const ( 16 AbsoluteTimeMode TimestampMode = iota 17 ElapsedTimeMode 18 IncrementalTimeMode 19 ) 20 21 type Timestamper struct { 22 Mode TimestampMode 23 TZ *time.Location 24 Formatter *strftime.Strftime 25 StartTimestamp time.Time 26 LastTimestamp time.Time 27 } 28 29 func NewTimestamper(format string, mode TimestampMode, timezone *time.Location) (*Timestamper, error) { 30 formatter, err := strftime.New(format, 31 strftime.WithMilliseconds('L'), 32 strftime.WithUnixSeconds('s'), 33 strftime.WithSpecification('f', microseconds)) 34 if err != nil { 35 return nil, err 36 } 37 now := time.Now() 38 return &Timestamper{ 39 Mode: mode, 40 TZ: timezone, 41 Formatter: formatter, 42 StartTimestamp: now, 43 LastTimestamp: now, 44 }, nil 45 } 46 47 func (t *Timestamper) CurrentTimestampString() string { 48 now := time.Now() 49 var s string 50 switch t.Mode { 51 case AbsoluteTimeMode: 52 s = t.Formatter.FormatString(time.Now().In(t.TZ)) 53 case ElapsedTimeMode: 54 s = formatDuration(t.Formatter, now.Sub(t.StartTimestamp)) 55 case IncrementalTimeMode: 56 s = formatDuration(t.Formatter, now.Sub(t.LastTimestamp)) 57 default: 58 log.Panic("unknown mode ", t.Mode) 59 } 60 t.LastTimestamp = now 61 return s 62 } 63 64 func formatDuration(formatter *strftime.Strftime, duration time.Duration) string { 65 return formatter.FormatString(time.Unix(0, duration.Nanoseconds()).UTC()) 66 } 67 68 var microseconds strftime.Appender 69 70 func init() { 71 microseconds = strftime.AppendFunc(func(b []byte, t time.Time) []byte { 72 microsecond := int(t.Nanosecond()) / int(time.Microsecond) 73 if microsecond == 0 { 74 return append(b, "000000"...) 75 } else { 76 length := int(math.Log10(float64(microsecond))) + 1 77 b = append(b, bytes.Repeat([]byte("0"), 6-length)...) 78 return append(b, strconv.Itoa(microsecond)...) 79 } 80 }) 81 }