2025-09-24 00:01:06 +02:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/ijt/go-anytime"
|
|
|
|
|
"github.com/itlightning/dateparse"
|
2025-09-24 08:31:22 +02:00
|
|
|
modnow "github.com/jinzhu/now"
|
2025-09-24 00:01:06 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type TimestampProccessor struct {
|
|
|
|
|
Config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewTP(conf *Config) *TimestampProccessor {
|
|
|
|
|
formats := []string{
|
|
|
|
|
time.UnixDate, time.RubyDate,
|
|
|
|
|
time.RFC1123, time.RFC1123Z, time.RFC3339, time.RFC3339Nano,
|
|
|
|
|
time.RFC822, time.RFC822Z, time.RFC850,
|
|
|
|
|
"Mon Jan 02 15:04:05 PM MST 2006", // linux date
|
|
|
|
|
"Mo. 02 Jan. 2006 15:04:05 MST", // freebsd date (fails, see golang/go/issues/75576)
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 08:31:22 +02:00
|
|
|
modnow.TimeFormats = append(modnow.TimeFormats, formats...)
|
2025-09-24 00:01:06 +02:00
|
|
|
|
|
|
|
|
return &TimestampProccessor{Config: *conf}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (tp *TimestampProccessor) ProcessTimestamps() error {
|
|
|
|
|
switch len(tp.Args) {
|
|
|
|
|
case 1:
|
|
|
|
|
return tp.SingleTimestamp(tp.Args[0])
|
|
|
|
|
case 2:
|
|
|
|
|
return tp.Calc(tp.Args[0], tp.Args[1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (tp *TimestampProccessor) SingleTimestamp(timestamp string) error {
|
|
|
|
|
ts, err := tp.Parse(timestamp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tp.Print(ts)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse uses 3 different timestamp parser modules to provide the maximum flexibility
|
|
|
|
|
func (tp *TimestampProccessor) Parse(timestamp string) (time.Time, error) {
|
|
|
|
|
reference := time.Now()
|
|
|
|
|
ts, err := anytime.Parse(timestamp, reference)
|
|
|
|
|
if err == nil {
|
|
|
|
|
return ts, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 08:31:22 +02:00
|
|
|
// anytime failed, try module modnow
|
|
|
|
|
ts, err = modnow.Parse(timestamp)
|
2025-09-24 00:01:06 +02:00
|
|
|
if err == nil {
|
|
|
|
|
return ts, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 08:31:22 +02:00
|
|
|
// modnow failed, try module dateparse
|
2025-09-24 00:07:00 +02:00
|
|
|
return dateparse.ParseAny(timestamp)
|
2025-09-24 00:01:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (tp *TimestampProccessor) Calc(timestampA, timestampB string) error {
|
2025-09-24 08:31:22 +02:00
|
|
|
tsA, err := tp.Parse(timestampA)
|
2025-09-24 00:01:06 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 08:31:22 +02:00
|
|
|
tsB, err := tp.Parse(timestampB)
|
2025-09-24 00:01:06 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch tp.Mode {
|
|
|
|
|
case ModeDiff:
|
|
|
|
|
var diff time.Duration
|
|
|
|
|
if tsA.Unix() > tsB.Unix() {
|
|
|
|
|
diff = tsA.Sub(tsB)
|
|
|
|
|
} else {
|
|
|
|
|
diff = tsB.Sub(tsA)
|
|
|
|
|
}
|
2025-09-24 08:31:22 +02:00
|
|
|
tp.Print(TPduration{TimestampProccessor: *tp, Data: diff})
|
|
|
|
|
|
2025-09-24 00:01:06 +02:00
|
|
|
case ModeAdd:
|
|
|
|
|
seconds := (tsB.Hour() * 3600) + (tsB.Minute() * 60) + tsB.Second()
|
2025-09-24 08:31:22 +02:00
|
|
|
sum := tsA.Add(time.Duration(seconds) * time.Second)
|
|
|
|
|
tp.Print(TPdatetime{TimestampProccessor: *tp, Data: sum})
|
2025-09-24 00:01:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-24 08:31:22 +02:00
|
|
|
func (tp *TimestampProccessor) Print(ts TimestampWriter) {
|
|
|
|
|
_, err := fmt.Fprintln(tp.Output, ts.String())
|
2025-09-24 00:01:06 +02:00
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("failed to print to given output handle: %s", err)
|
|
|
|
|
}
|
|
|
|
|
}
|