tme

Toggl like Time Manager
git clone git://gtms.dev/tme
Log | Files | Refs

time_context.go (2794B)


      1 package main
      2 
      3 import (
      4 	"fmt"
      5 	"strings"
      6 	"time"
      7 )
      8 
      9 const (
     10 	FileNameLayout = "0601021504"
     11 	DataTimeLayout = time.RFC3339
     12 )
     13 
     14 type TimeContext struct {
     15 	context time.Time
     16 }
     17 
     18 func NewTime(t time.Time) *TimeContext {
     19 	return &TimeContext{t}
     20 }
     21 
     22 func NewTimeToday() *TimeContext {
     23 	return &TimeContext{time.Now()}
     24 }
     25 
     26 func (et *TimeContext) ParseArgRelative(start time.Time, raw string) (time.Time, error) {
     27 	dur, err := time.ParseDuration(raw)
     28 	return start.Add(dur), err
     29 }
     30 
     31 // TODO(tms) 11.02.23: Simplify
     32 func (et *TimeContext) ParseArgDir(raw string, shiftRight bool) (time.Time, error) {
     33 	parts := strings.Split(raw, " ")
     34 	hour, min, sec := et.context.Clock()
     35 	year, mon, day := et.context.Date()
     36 
     37 	zeroHour := 0
     38 	zeroTime := 0
     39 	if shiftRight {
     40 		zeroTime = 59
     41 		zeroHour = 23
     42 	}
     43 
     44 	var parsed bool
     45 	part := parts[0]
     46 
     47 	t, err := time.Parse("15", part)
     48 	if err == nil {
     49 		parsed = true
     50 		hour = t.Hour()
     51 		min = zeroTime
     52 		sec = zeroTime
     53 	}
     54 
     55 	t, err = time.Parse("15:4", part)
     56 	if err == nil {
     57 		parsed = true
     58 		hour = t.Hour()
     59 		min = t.Minute()
     60 		sec = zeroTime
     61 	}
     62 
     63 	t, err = time.Parse("15:4:5", part)
     64 	if err == nil {
     65 		parsed = true
     66 		hour = t.Hour()
     67 		min = t.Minute()
     68 		sec = t.Second()
     69 	}
     70 
     71 	t, err = time.Parse("2/1", part)
     72 	if err == nil {
     73 		parsed = true
     74 		hour = zeroHour
     75 		min = zeroTime
     76 		sec = zeroTime
     77 		day = t.Day()
     78 		mon = t.Month()
     79 		year = et.context.Year()
     80 	}
     81 
     82 	t, err = time.Parse("1/2006", part)
     83 	if err == nil {
     84 		parsed = true
     85 		hour = zeroHour
     86 		min = zeroTime
     87 		sec = zeroTime
     88 
     89 		zeroDay := 1
     90 		firstOfMonth := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, et.context.Location())
     91 		lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
     92 		if shiftRight {
     93 			zeroDay = lastOfMonth.Day()
     94 		}
     95 
     96 		day = zeroDay
     97 
     98 		mon = t.Month()
     99 		year = t.Year()
    100 	}
    101 
    102 	t, err = time.Parse("2/1/2006", part)
    103 	if err == nil {
    104 		parsed = true
    105 		hour = zeroHour
    106 		min = zeroTime
    107 		sec = zeroTime
    108 		day = t.Day()
    109 		mon = t.Month()
    110 		year = t.Year()
    111 	}
    112 
    113 	if !parsed && len(raw) > 0 {
    114 		return time.Now(), fmt.Errorf("Cannot parse %q", raw)
    115 	}
    116 
    117 	if len(parts) > 1 {
    118 		part = parts[1]
    119 		t, err := time.Parse("2", part)
    120 		if err == nil {
    121 			day = t.Day()
    122 			mon = et.context.Month()
    123 			year = et.context.Year()
    124 		}
    125 
    126 		t, err = time.Parse("2/1", part)
    127 		if err == nil {
    128 			day = t.Day()
    129 			mon = t.Month()
    130 			year = et.context.Year()
    131 		}
    132 
    133 		t, err = time.Parse("2/1/2006", part)
    134 		if err == nil {
    135 			day = t.Day()
    136 			mon = t.Month()
    137 			year = t.Year()
    138 		}
    139 	}
    140 
    141 	return time.Date(
    142 		year,
    143 		mon,
    144 		day,
    145 		hour,
    146 		min,
    147 		sec,
    148 		0,
    149 		et.context.Location(),
    150 	), nil
    151 }
    152 
    153 func (et *TimeContext) ParseEntry(raw string) (time.Time, error) {
    154 	t, err := time.Parse(DataTimeLayout, raw)
    155 	return time.Date(
    156 		t.Year(),
    157 		t.Month(),
    158 		t.Day(),
    159 		t.Hour(),
    160 		t.Minute(),
    161 		t.Second(),
    162 		0,
    163 		et.context.Location(),
    164 	), err
    165 }