commit 6304741cb9c7d9fd0749ec6bb2a439a5ac923198
parent 43b7ada48fb26971cb5e0cb256d82157fb47a736
Author: Tomas Nemec <nemi@skaut.cz>
Date: Sat, 11 Feb 2023 00:44:10 +0100
feat: better parsing of time
Diffstat:
M | command.go | | | 9 | +++++---- |
M | tme/time.go | | | 117 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
A | tme/time_test.go | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 151 insertions(+), 19 deletions(-)
diff --git a/command.go b/command.go
@@ -221,7 +221,7 @@ func (c Command) report() {
}
for _, entry := range entries {
- if entry.Start.After(sinceTime) {
+ if entry.Start.After(sinceTime) || entry.Start.Equal(sinceTime) {
duration += entry.Duration()
formatEntry(group, entry)
}
@@ -248,15 +248,16 @@ func formatEntries(group tme.Group, entryTime *tme.Time) {
func formatEntry(group tme.Group, entry tme.Entry) {
groupPath := group.Path
duration := entry.Duration().Round(time.Second)
+ timeLayout := "15:04 02/01/2006"
switch e := entry.(type) {
case tme.CompletedEntry:
var start string
- start = e.Start.Format(tme.DateTimeLayout)
- stop := e.Stop.Format(tme.DateTimeLayout)
+ start = e.Start.Format(timeLayout)
+ stop := e.Stop.Format(timeLayout)
fmt.Printf("%s\t%s\t%v\t%s\n", groupPath, start, stop, duration)
case tme.RunningEntry:
- start := e.Start.Format(tme.DateTimeLayout)
+ start := e.Start.Format(timeLayout)
fmt.Printf("%s\t%s\t%s\t%s\n", groupPath, start, "running", duration)
}
}
diff --git a/tme/time.go b/tme/time.go
@@ -1,10 +1,12 @@
package tme
-import "time"
+import (
+ "fmt"
+ "strings"
+ "time"
+)
const (
- TimeLayout = "15:04"
- DateTimeLayout = "15:04 02/01/2006"
FileNameLayout = "0601021504"
DataTimeLayout = time.RFC3339
)
@@ -21,18 +23,103 @@ func NewTimeToday() *Time {
return &Time{time.Now()}
}
+// TODO(tms) 11.02.23: Simplify
func (et *Time) ParseArg(raw string) (time.Time, error) {
- t, err := time.Parse(TimeLayout, raw)
- return time.Date(
- et.context.Year(),
- et.context.Month(),
- et.context.Day(),
- t.Hour(),
- t.Minute(),
- 0,
- 0,
- et.context.Location(),
- ), err
+ parts := strings.Split(raw, " ")
+ hour := et.context.Hour()
+ min := et.context.Minute()
+ sec := et.context.Second()
+ year, mon, day := et.context.Date()
+
+ var parsed bool
+ part := parts[0]
+
+ t, err := time.Parse("15", part)
+ if err == nil {
+ parsed = true
+ hour = t.Hour()
+ min = 0
+ sec = 0
+ }
+
+ t, err = time.Parse("15:4", part)
+ if err == nil {
+ parsed = true
+ hour = t.Hour()
+ min = t.Minute()
+ sec = 0
+ }
+
+ t, err = time.Parse("15:4:5", part)
+ if err == nil {
+ parsed = true
+ hour = t.Hour()
+ min = t.Minute()
+ sec = t.Second()
+ }
+
+ t, err = time.Parse("2/1", part)
+ if err == nil {
+ parsed = true
+ hour = 0
+ min = 0
+ sec = 0
+ day = t.Day()
+ mon = t.Month()
+ year = et.context.Year()
+ }
+
+ t, err = time.Parse("1/2006", part)
+ if err == nil {
+ parsed = true
+ hour = 0
+ min = 0
+ sec = 0
+ day = 1
+ mon = t.Month()
+ year = t.Year()
+ }
+
+ t, err = time.Parse("2/1/2006", part)
+ if err == nil {
+ parsed = true
+ hour = 0
+ min = 0
+ sec = 0
+ day = t.Day()
+ mon = t.Month()
+ year = t.Year()
+ }
+
+ if !parsed && len(raw) > 0 {
+ return time.Now(), fmt.Errorf("Cannot parse %q", raw)
+ }
+
+ if len(parts) > 1 {
+ part = parts[1]
+ t, err := time.Parse("2", part)
+ if err == nil {
+ day = t.Day()
+ mon = et.context.Month()
+ year = et.context.Year()
+ }
+
+ t, err = time.Parse("2/1", part)
+ if err == nil {
+ day = t.Day()
+ mon = t.Month()
+ year = et.context.Year()
+ }
+
+ t, err = time.Parse("2/1/2006", part)
+ if err == nil {
+ day = t.Day()
+ mon = t.Month()
+ year = t.Year()
+ }
+ }
+
+ return time.Date(year, mon, day, hour, min, sec, 0, et.context.Location()), nil
}
func (et *Time) ParseEntry(raw string) (time.Time, error) {
@@ -43,7 +130,7 @@ func (et *Time) ParseEntry(raw string) (time.Time, error) {
t.Day(),
t.Hour(),
t.Minute(),
- 0,
+ t.Second(),
0,
et.context.Location(),
), err
diff --git a/tme/time_test.go b/tme/time_test.go
@@ -0,0 +1,44 @@
+package tme
+
+import (
+ "testing"
+ "time"
+)
+
+func TestParseArg(t *testing.T) {
+ layout := "15:4:5 2/1/2006"
+ context, _ := time.Parse(layout, "1:1:1 1/1/2001")
+ var check = func(raw string, expected string) {
+ t.Helper()
+ t.Run("", func(b *testing.T) {
+ b.Helper()
+ tmeTime := NewTime(context)
+ expected, _ := time.Parse(layout, expected)
+ parsed, err := tmeTime.ParseArg(raw)
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ if !parsed.Equal(expected) {
+ b.Errorf("Parsed %v; Expected %v", parsed, expected)
+ }
+ })
+ }
+
+ check("5", "5:0:0 1/1/2001")
+ check("5:5", "5:5:0 1/1/2001")
+ check("5:5:5", "5:5:5 1/1/2001")
+ check("5:5 5", "5:5:0 5/1/2001")
+ check("5:5 5/5", "5:5:0 5/5/2001")
+ check("5:5 5/5/2005", "5:5:0 5/5/2005")
+
+ check("5/5", "0:0:0 5/5/2001")
+ check("5/5/2005", "0:0:0 5/5/2005")
+ check("5/2005", "0:0:0 1/5/2005")
+
+ check("5:05", "5:5:0 1/1/2001")
+ check("05:05", "5:5:0 1/1/2001")
+ check("05:5 05/5/2005", "5:5:0 5/5/2005")
+ check("5:5 5/05/2005", "5:5:0 5/5/2005")
+ check("5:05 5/05/2005", "5:5:0 5/5/2005")
+}