package gotime import ( "errors" "strings" "time" ) type Timer struct { Id int Beg time.Time End time.Time Tags []string timeFormat string } // CreateTimerFromString takes a string in the format of the lines from the data file // and builds a timer from it. func CreateTimerFromString(st string) (*Timer, error) { var err error t := new(Timer) t.timeFormat = "20060102T150405Z" flds := strings.Fields(st) if len(flds) > 1 && flds[0] == "inc" { // Start Time if len(flds) >= 2 { if t.Beg, err = time.Parse(t.timeFormat, flds[1]); err != nil { return t, err } } // End Time if len(flds) >= 4 && flds[2] == "-" { if t.End, err = time.Parse(t.timeFormat, flds[3]); err != nil { return t, err } } var inTags bool for i := range flds { if flds[i] == "#" { inTags = true continue } if inTags { tg := strings.Trim(flds[i], "\"") t.AddTag(tg) } } } return t, err } func (t *Timer) Start() { if t.Beg.IsZero() { t.Beg = time.Now() } } func (t *Timer) Stop() { if t.End.IsZero() { t.End = time.Now() } } func (t *Timer) SetId(i int) { t.Id = i } func (t *Timer) SetStart(tm time.Time) error { if !t.End.IsZero() && !tm.Before(t.End) { return errors.New("Beginning time must be before End") } t.Beg = tm return nil } func (t *Timer) SetEnd(tm time.Time) error { if !tm.After(t.Beg) { return errors.New("End time must be after Beginning") } t.End = tm return nil } func (t *Timer) IsRunning() bool { return !t.Beg.IsZero() && t.End.IsZero() } // AddTag adds the tag tg to this timer func (t *Timer) AddTag(tg string) { if !t.HasTag(tg) { t.Tags = append(t.Tags, tg) } } // RemoveTag removes the tag tg from this timer func (t *Timer) RemoveTag(tg string) { for i := 0; i < len(t.Tags); i++ { if t.Tags[i] == tg { t.Tags = append(t.Tags[:i], t.Tags[i+1:]...) } } } // HasTag returns if this timer has the tag func (t *Timer) HasTag(tg string) bool { for i := range t.Tags { if t.Tags[i] == tg { return true } } return false } func (t *Timer) ToString() string { if t.Beg.IsZero() { return "" } timeFormat := "20060102T150405Z" ret := "inc " + t.Beg.Format(timeFormat) if !t.End.IsZero() { ret += " - " + t.End.Format(timeFormat) } if len(t.Tags) > 0 { ret += " # " for i := range t.Tags { if TagIsMultiword(t.Tags[i]) { ret += "\"" } ret += t.Tags[i] if TagIsMultiword(t.Tags[i]) { ret += "\"" } ret += " " } ret = ret[:len(ret)-1] } return ret } func (t *Timer) ToJsonString() string { if t.Beg.IsZero() { return "" } timeFormat := "20060102T150405Z" ret := "{\"start\":\"" + t.Beg.Format(timeFormat) + "\"," if !t.End.IsZero() { ret += "\"end\":\"" + t.End.Format(timeFormat) + "\"," } if len(t.Tags) > 0 { ret += "\"tags\":[" for i := range t.Tags { ret += "\"" + t.Tags[i] + "\"," } // Move trailing ',' to end ret = ret[:len(ret)-1] + "]," } // Trim trailing , ret = ret[:len(ret)-1] + "}" return ret }