summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2013-08-28 00:49:03 +0200
committerKevin Chabowski <kevin@kch42.de>2013-08-28 00:49:03 +0200
commit24a1a8b96f133ff84ede87e13f4ffd7c7b316606 (patch)
treeeaf86574b9e6314f2ef069e1563501bc08035b36
parent57872925e3b438122520a245caacf2843bebf185 (diff)
downloadmailremind-24a1a8b96f133ff84ede87e13f4ffd7c7b316606.tar.gz
mailremind-24a1a8b96f133ff84ede87e13f4ffd7c7b316606.tar.bz2
mailremind-24a1a8b96f133ff84ede87e13f4ffd7c7b316606.zip
Chronos infos can now be stringified and parsed.
-rw-r--r--chronos/chronos.go64
-rw-r--r--chronos/chronos_test.go40
2 files changed, 88 insertions, 16 deletions
diff --git a/chronos/chronos.go b/chronos/chronos.go
index e66fc76..1d2c943 100644
--- a/chronos/chronos.go
+++ b/chronos/chronos.go
@@ -1,12 +1,18 @@
package chronos
import (
+ "errors"
+ "fmt"
"math"
+ "strconv"
+ "strings"
"time"
)
type TimeUnit int
+const timefmt = "2006-01-02 15:04:05"
+
const (
Minute TimeUnit = iota
Hour
@@ -18,6 +24,15 @@ const (
var nilTime time.Time
+var tuLookup = map[string]TimeUnit{
+ "Minute": Minute,
+ "Hour": Hour,
+ "Day": Day,
+ "Week": Week,
+ "Month": Month,
+ "Year": Year,
+}
+
func (tu TimeUnit) String() string {
switch tu {
case Minute:
@@ -98,6 +113,10 @@ type Frequency struct {
Count uint
}
+func (f Frequency) String() string {
+ return fmt.Sprintf("%d %s", f.Count, f.Unit)
+}
+
func (f Frequency) addTo(t time.Time, mul uint) time.Time {
sec := t.Second()
min := t.Minute()
@@ -163,3 +182,48 @@ func (c Chronos) NextAfter(t time.Time) time.Time {
return nilTime // Should actually never happen...
}
+
+func (c Chronos) String() string {
+ s := c.Start.UTC().Format(timefmt)
+ if c.Freq.Count > 0 {
+ s += " +" + c.Freq.String()
+ if !c.End.IsZero() {
+ s += " !" + c.End.UTC().Format(timefmt)
+ }
+ }
+ return s
+}
+
+func ParseChronos(s string) (c Chronos, err error) {
+ elems := strings.Split(s, " ")
+
+ switch len(elems) {
+ case 6: // Everything specified
+ _end := elems[4] + " " + elems[5]
+ if c.End, err = time.ParseInLocation(timefmt, _end[1:], time.UTC); err != nil {
+ return
+ }
+ fallthrough
+ case 4: // start time and frequency
+ var count uint64
+ if count, err = strconv.ParseUint(elems[2][1:], 10, 32); err != nil {
+ return
+ }
+ c.Freq.Count = uint(count)
+
+ var ok bool
+ if c.Freq.Unit, ok = tuLookup[elems[3]]; !ok {
+ err = fmt.Errorf("Unknown timeunit %s", elems[3])
+ return
+ }
+ fallthrough
+ case 2: // Only start time
+ if c.Start, err = time.ParseInLocation(timefmt, elems[0]+" "+elems[1], time.UTC); err != nil {
+ return
+ }
+ default:
+ err = errors.New("Unknown chronos format")
+ }
+
+ return
+}
diff --git a/chronos/chronos_test.go b/chronos/chronos_test.go
index 692af14..1798b4c 100644
--- a/chronos/chronos_test.go
+++ b/chronos/chronos_test.go
@@ -6,32 +6,40 @@ import (
)
func mktime(y int, month time.Month, d, h, min int) time.Time {
- return time.Date(y, month, d, h, min, 0, 0, time.Local)
+ return time.Date(y, month, d, h, min, 0, 0, time.UTC)
}
func TestChronos(t *testing.T) {
tbl := []struct {
- start time.Time
- end time.Time
- unit TimeUnit
- count uint
- now time.Time
- want time.Time
+ chronos string
+ now time.Time
+ want time.Time
}{
- {mktime(1991, 4, 30, 0, 0), nilTime, Year, 1, mktime(2013, 8, 26, 13, 37), mktime(2014, 4, 30, 0, 0)},
- {mktime(2013, 1, 1, 0, 0), nilTime, Year, 0, mktime(2013, 8, 26, 13, 37), nilTime},
- {mktime(2013, 1, 1, 0, 0), nilTime, Year, 0, mktime(2012, 1, 1, 0, 0), mktime(2013, 1, 1, 0, 0)},
- {mktime(1900, 12, 24, 12, 34), nilTime, Year, 5, mktime(2013, 8, 26, 13, 37), mktime(2015, 12, 24, 12, 34)},
- {mktime(1900, 12, 24, 12, 34), mktime(2010, 1, 1, 1, 1), Year, 5, mktime(2013, 8, 26, 13, 37), nilTime},
- {mktime(2013, 8, 1, 4, 2), nilTime, Week, 3, mktime(2013, 8, 26, 13, 37), mktime(2013, 9, 12, 4, 2)},
- {mktime(2013, 8, 26, 13, 37), nilTime, Year, 0, mktime(2013, 8, 26, 13, 37), mktime(2013, 8, 26, 13, 37)},
- {mktime(2013, 8, 25, 13, 37), nilTime, Day, 1, mktime(2013, 8, 26, 13, 37), mktime(2013, 8, 26, 13, 37)},
+ {"1991-04-30 00:00:00 +1 Year", mktime(2013, 8, 26, 13, 37), mktime(2014, 4, 30, 0, 0)},
+ {"2013-01-01 00:00:00", mktime(2013, 8, 26, 13, 37), nilTime},
+ {"2013-01-01 00:00:00", mktime(2012, 1, 1, 0, 0), mktime(2013, 1, 1, 0, 0)},
+ {"1900-12-24 12:34:00 +5 Year", mktime(2013, 8, 26, 13, 37), mktime(2015, 12, 24, 12, 34)},
+ {"1900-12-24 12:34:00 +5 Year !2010-01-01 01:01:00", mktime(2013, 8, 26, 13, 37), nilTime},
+ {"2013-08-01 04:02:00 +3 Week", mktime(2013, 8, 26, 13, 37), mktime(2013, 9, 12, 4, 2)},
+ {"2013-08-26 13:37:00", mktime(2013, 8, 26, 13, 37), mktime(2013, 8, 26, 13, 37)},
+ {"2013-08-25 13:37:00 +1 Day", mktime(2013, 8, 26, 13, 37), mktime(2013, 8, 26, 13, 37)},
+ {"2012-12-31 23:59:00 +100 Minute", mktime(2013, 1, 1, 0, 0), mktime(2013, 1, 1, 1, 39)},
}
for i, e := range tbl {
- have := Chronos{e.start, e.end, Frequency{e.unit, e.count}}.NextAfter(e.now)
+ c, err := ParseChronos(e.chronos)
+ if err != nil {
+ t.Errorf("#%d: Failed parsing \"%s\": %s", i, e.chronos, err)
+ continue
+ }
+ have := c.NextAfter(e.now)
if !have.Equal(e.want) {
t.Errorf("#%d: Want: %s, Have: %s", i, e.want, have)
}
+
+ if s := c.String(); s != e.chronos {
+ t.Errorf("#%d: String() failed: \"%s\" != \"%s\"", i, e.chronos, s)
+ }
+
}
}