package gime import ( "errors" "time" "github.com/pborman/uuid" ) // Entry is a time entry type TimeEntry struct { uuid string start time.Time end time.Time tags *TagCollection } // CreateTimeEntry creates an entry with the given parameters and returns it. // An error is returned if no start time is given or if the end time given is // non-zero and earlier than the start time. func CreateTimeEntry(s, e time.Time, t *TagCollection) (*TimeEntry, error) { ret := new(TimeEntry) ret.uuid = uuid.New() if s.IsZero() { // No start time given, return error return ret, errors.New("No start time given") } ret.start = s if !e.IsZero() { if !e.After(s) { // Given end time is earlier than start time return ret, errors.New("End time is before start time") } } ret.end = e ret.tags = t return ret, nil } // GetUUID returns the UUID for the entry func (t *TimeEntry) GetUUID() string { return t.uuid } // GetStart returns the start time for the entry func (t *TimeEntry) GetStart() time.Time { return t.start } // SetStart sets the start time on the time entry func (t *TimeEntry) SetStart(s time.Time) { t.start = s } // GetEnd returns the end time for the entry func (t *TimeEntry) GetEnd() time.Time { return t.end } // SetEnd sets the end time on the time entry func (t *TimeEntry) SetEnd(e time.Time) { t.end = e } // IsActive return true if start is earlier than now and end is zero func (t *TimeEntry) IsActive() bool { return time.Now().After(t.start) && !t.end.IsZero() } // GetTags returns all of the tags associated with this time entry func (t *TimeEntry) GetTags() *TagCollection { return t.tags } // HasTag returns if the time entry contains a specific tag func (t *TimeEntry) HasTag(s string) bool { for i := 0; i < t.tags.Length(); i++ { if t.tags.Get(i) == s { return true } } return false } // AddTag adds a tag to the time entry (if it isn't already there) func (t *TimeEntry) AddTag(s string) { if !t.HasTag(s) { t.tags.Push(s) } } // RemoveTag removes a tag from the time entry func (t *TimeEntry) RemoveTag(s string) { i := t.tags.Index(s) if i != -1 { t.tags.Remove(i) } } // Equals tests if the passed time entry is the same // as the one that we're calling it on. func (t *TimeEntry) Equals(tst *TimeEntry) bool { return t.uuid == tst.uuid } // StartsToday returns if the timer's start time is today func (t *TimeEntry) StartsToday() bool { currTime := time.Now() dur := int64(currTime.Hour())*int64(time.Hour) + int64(currTime.Minute())*int64(time.Minute) return int64(time.Since(t.GetStart())) < dur } // StartsToday returns if the timer's end time is today func (t *TimeEntry) EndsToday() bool { currTime := time.Now() dur := int64(currTime.Hour())*int64(time.Hour) + int64(currTime.Minute())*int64(time.Minute) return int64(time.Since(t.GetEnd())) < dur } // IsRunning returns if the timer is still running func (t *TimeEntry) IsRunning() bool { return t.GetEnd().IsZero() } // String formats a string of the time entry func (t *TimeEntry) String() string { var ret string ret = t.GetStart().Format(time.RFC3339) if !t.GetEnd().IsZero() { ret += " - " + t.GetEnd().Format(time.RFC3339) } tags := t.GetTags() if tags.Length() > 0 { ret += " [ " for i := 0; i < tags.Length(); i++ { ret += tags.Get(i) + " " } ret += "]" } if t.GetEnd().IsZero() { ret += " Running" } if t.GetUUID() != "" { ret += " (" + t.GetUUID() + ")" } return ret }