185 lines
3.8 KiB
Go
185 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
func GetRoundToDuration() time.Duration {
|
|
var dur time.Duration
|
|
var err error
|
|
if dur, err = time.ParseDuration(cfg.Get("roundto")); err != nil {
|
|
cfg.Set("roundto", DefRoundTo)
|
|
dur, _ = time.ParseDuration(DefRoundTo)
|
|
}
|
|
return dur
|
|
}
|
|
|
|
func DurationToDecimal(dur time.Duration) float64 {
|
|
mins := dur.Minutes() - (dur.Hours() * 60)
|
|
return dur.Hours() + (mins / 60)
|
|
}
|
|
|
|
// pullRemoveTagsFromArgs takes a list of arguments, removes all 'remove tags' from them
|
|
// then returns the tags and the remaining args
|
|
func pullRemoveTagsFromArgs(args []string) ([]string, []string) {
|
|
var tags, rem []string
|
|
for _, opt := range args {
|
|
if opt[0] == '-' {
|
|
tags = append(tags, opt[1:])
|
|
} else {
|
|
rem = append(rem, opt)
|
|
}
|
|
}
|
|
return tags, rem
|
|
}
|
|
|
|
// pullTagsFromArgs takes a list of arguments, removes all tags from them
|
|
// then returns the tags and the remaining args
|
|
func pullTagsFromArgs(args []string) ([]string, []string) {
|
|
var tags, rem []string
|
|
for _, opt := range args {
|
|
if opt[0] == '+' {
|
|
tags = append(tags, opt[1:])
|
|
} else {
|
|
rem = append(rem, opt)
|
|
}
|
|
}
|
|
return tags, rem
|
|
}
|
|
|
|
func parseFuzzyTime(t string) (time.Time, error) {
|
|
var ret time.Time
|
|
var err error
|
|
for i := range fuzzyFormats {
|
|
ret, err = time.Parse(fuzzyFormats[i], t)
|
|
if err == nil {
|
|
// Make sure it's in the local timezone
|
|
tz := time.Now().Format("Z07:00")
|
|
t = ret.Format("2006-01-02T15:04:05") + tz
|
|
if ret, err = time.Parse(time.RFC3339, t); err != nil {
|
|
return ret, err
|
|
}
|
|
// Check for zero on year/mo/day
|
|
if ret.Year() == 0 && ret.Month() == time.January && ret.Day() == 1 {
|
|
ret = ret.AddDate(time.Now().Year(), int(time.Now().Month())-1, time.Now().Day()-1)
|
|
}
|
|
return ret, nil
|
|
}
|
|
}
|
|
return time.Time{}, errors.New("Unable to parse time: " + t)
|
|
}
|
|
|
|
func friendlyFormatForTime(t time.Time) string {
|
|
nowTime := time.Now()
|
|
if t.Year() != nowTime.Year() || t.Month() != nowTime.Month() {
|
|
return "2006-01-02 15:04"
|
|
} else if t.Day() != nowTime.Day() {
|
|
return "01/02 15:04"
|
|
}
|
|
return "15:04"
|
|
}
|
|
|
|
// timeToFriendlyString returns an easier to read version of the time
|
|
// giving enough details that the user should be fine inferring the rest
|
|
func timeToFriendlyString(t time.Time) string {
|
|
return t.Format(friendlyFormatForTime(t))
|
|
}
|
|
|
|
func sinceToString(tm time.Time) string {
|
|
return diffToString(tm, time.Now())
|
|
}
|
|
|
|
func diffToString(tm1, tm2 time.Time) string {
|
|
ret := ""
|
|
yr, mo, dy, hr, mn, sc := diff(tm1, tm2)
|
|
higher := false
|
|
|
|
if yr > 0 {
|
|
ret += fmt.Sprintf("%4dy ", yr)
|
|
higher = true
|
|
}
|
|
if mo > 0 || higher {
|
|
ret += fmt.Sprintf("%2dm ", mo)
|
|
higher = true
|
|
}
|
|
if dy > 0 || higher {
|
|
ret += fmt.Sprintf("%2dd ", dy)
|
|
higher = true
|
|
}
|
|
if hr > 0 || higher {
|
|
ret += fmt.Sprintf("%2dh ", hr)
|
|
higher = true
|
|
}
|
|
if mn > 0 || higher {
|
|
ret += fmt.Sprintf("%2dm ", mn)
|
|
higher = true
|
|
}
|
|
if sc > 0 || higher {
|
|
ret += fmt.Sprintf("%2ds", sc)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func padRight(st string, l int) string {
|
|
for len(st) < l {
|
|
st = st + " "
|
|
}
|
|
return st
|
|
}
|
|
|
|
func padLeft(st string, l int) string {
|
|
for len(st) < l {
|
|
st = " " + st
|
|
}
|
|
return st
|
|
}
|
|
|
|
func diff(a, b time.Time) (year, month, day, hour, min, sec int) {
|
|
if a.Location() != b.Location() {
|
|
b = b.In(a.Location())
|
|
}
|
|
if a.After(b) {
|
|
a, b = b, a
|
|
}
|
|
y1, M1, d1 := a.Date()
|
|
y2, M2, d2 := b.Date()
|
|
|
|
h1, m1, s1 := a.Clock()
|
|
h2, m2, s2 := b.Clock()
|
|
|
|
year = int(y2 - y1)
|
|
month = int(M2 - M1)
|
|
day = int(d2 - d1)
|
|
hour = int(h2 - h1)
|
|
min = int(m2 - m1)
|
|
sec = int(s2 - s1)
|
|
|
|
// Normalize negative values
|
|
if sec < 0 {
|
|
sec += 60
|
|
min--
|
|
}
|
|
if min < 0 {
|
|
min += 60
|
|
hour--
|
|
}
|
|
if hour < 0 {
|
|
hour += 24
|
|
day--
|
|
}
|
|
if day < 0 {
|
|
// days in month:
|
|
t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)
|
|
day += 32 - t.Day()
|
|
month--
|
|
}
|
|
if month < 0 {
|
|
month += 12
|
|
year--
|
|
}
|
|
|
|
return
|
|
}
|