diff --git a/README.md b/README.md index 23d353d..f3d4a9b 100644 --- a/README.md +++ b/README.md @@ -77,30 +77,30 @@ Import the library: Simplest way: - nextTime := cronexpr.Parse("0 0 29 2 *").Next(time.Now()) + nextTime := cronexpr.MustParse("0 0 29 2 *").Next(time.Now()) Assuming `time.Now()` is "2013-08-29 09:28:00", then `nextTime` will be "2016-02-29 00:00:00". You can keep the returned Expression pointer around if you want to reuse it: - expr := cronexpr.Parse("0 0 29 2 *") + expr := cronexpr.MustParse("0 0 29 2 *") nextTime := expr.Next(time.Now()) ... nextTime = expr.Next(nextTime) Use `time.IsZero()` to find out whether a valid time was returned. For example, - cronexpr.Parse("* * * * * 1980").Next(time.Now()).IsZero() + cronexpr.MustParse("* * * * * 1980").Next(time.Now()).IsZero() will return `true`, whereas - cronexpr.Parse("* * * * * 2050").Next(time.Now()).IsZero() + cronexpr.MustParse("* * * * * 2050").Next(time.Now()).IsZero() will return `false` (as of 2013-08-29...) You may also query for `n` next time stamps: - cronexpr.Parse("0 0 29 2 *").NextN(time.Now(), 5) + cronexpr.MustParse("0 0 29 2 *").NextN(time.Now(), 5) which returns a slice of time.Time objects, containing the following time stamps (as of 2013-08-30): @@ -111,7 +111,7 @@ which returns a slice of time.Time objects, containing the following time stamps 2032-02-29 00:00:00 The time zone of time values returned by `Next` and `NextN` is always the -time zone of the time value passed as argument, unless zero time value is +time zone of the time value passed as argument, unless a zero time value is returned. API diff --git a/cronexpr.go b/cronexpr.go index 62f1bc8..2fc7477 100644 --- a/cronexpr.go +++ b/cronexpr.go @@ -45,11 +45,12 @@ type Expression struct { /******************************************************************************/ -// Parse returns a new Expression pointer. It expects a well-formed cron expression. -// If a malformed cron expression is supplied, the result is undefined. See -// for documentation -// about what is a well-formed cron expression from this library point of view. -func Parse(cronLine string) *Expression { +// MustParse returns a new Expression pointer. It expects a well-formed cron +// expression. If a malformed cron expression is supplied, it will `panic`. +// See for documentation +// about what is a well-formed cron expression from this library's point of +// view. +func MustParse(cronLine string) *Expression { cronLineNormalized := cronNormalize(cronLine) // Split into fields @@ -73,7 +74,7 @@ func Parse(cronLine string) *Expression { // At this point, we should have at least 7 fields. Fields beyond the // seventh one, if any, are ignored. if len(cronFields) < 7 { - panic("Malformed cron expression\n") + panic("MustParse(): Not enough fields in the cron time expression\n") } // Generic parser can be used for most fields diff --git a/cronexpr_test.go b/cronexpr_test.go index 25ec128..1207eb3 100644 --- a/cronexpr_test.go +++ b/cronexpr_test.go @@ -13,10 +13,10 @@ package cronexpr_test /******************************************************************************/ import ( - "github.com/gorhill/cronexpr" - "testing" "time" + + "github.com/gorhill/cronexpr" ) /******************************************************************************/ @@ -123,7 +123,7 @@ func TestExpressions(t *testing.T) { for _, test := range crontests { for _, times := range test.times { from, _ := time.Parse("2006-01-02 15:04:05", times.from) - next := cronexpr.Parse(test.expr).Next(from) + next := cronexpr.MustParse(test.expr).Next(from) nextstr := next.Format(test.layout) if nextstr != times.next { t.Errorf(`("%s").Next("%s") = "%s", got "%s"`, test.expr, times.from, times.next, nextstr) @@ -134,18 +134,41 @@ func TestExpressions(t *testing.T) { func TestZero(t *testing.T) { from, _ := time.Parse("2006-01-02", "2013-08-31") - next := cronexpr.Parse("* * * * * 1980").Next(from) + next := cronexpr.MustParse("* * * * * 1980").Next(from) if next.IsZero() == false { t.Error(`("* * * * * 1980").Next("2013-08-31").IsZero() returned 'false', expected 'true'`) } - next = cronexpr.Parse("* * * * * 2050").Next(from) + next = cronexpr.MustParse("* * * * * 2050").Next(from) if next.IsZero() == true { t.Error(`("* * * * * 2050").Next("2013-08-31").IsZero() returned 'true', expected 'false'`) } - next = cronexpr.Parse("* * * * * 2099").Next(time.Time{}) + next = cronexpr.MustParse("* * * * * 2099").Next(time.Time{}) if next.IsZero() == false { t.Error(`("* * * * * 2014").Next(time.Time{}).IsZero() returned 'true', expected 'false'`) } } + +func TestNextN(t *testing.T) { + expected := []string{ + "Sat, 30 Nov 2013 00:00:00", + "Sat, 29 Mar 2014 00:00:00", + "Sat, 31 May 2014 00:00:00", + "Sat, 30 Aug 2014 00:00:00", + "Sat, 29 Nov 2014 00:00:00", + } + from, _ := time.Parse("2006-01-02 15:04:05", "2013-09-02 08:44:30") + result := cronexpr.MustParse("0 0 * * 6#5").NextN(from, uint(len(expected))) + if len(result) != len(expected) { + t.Errorf(`MustParse("0 0 * * 6#5").NextN("2013-09-02 08:44:30", 5):\n"`) + t.Errorf(` Expected %d returned time values but got %d instead`, len(expected), len(result)) + } + for i, next := range result { + nextStr := next.Format("Mon, 2 Jan 2006 15:04:15") + if nextStr != expected[i] { + t.Errorf(`MustParse("0 0 * * 6#5").NextN("2013-09-02 08:44:30", 5):\n"`) + t.Errorf(` result[%d]: expected "%s" but got "%s"`, i, expected[i], nextStr) + } + } +} diff --git a/example_test.go b/example_test.go index ca4871a..38fa2ea 100644 --- a/example_test.go +++ b/example_test.go @@ -24,7 +24,7 @@ import ( // ExampleParse func ExampleParse() { t := time.Date(2013, time.August, 31, 0, 0, 0, 0, time.UTC) - nextTimes := cronexpr.Parse("0 0 29 2 *").NextN(t, 5) + nextTimes := cronexpr.MustParse("0 0 29 2 *").NextN(t, 5) for i := range nextTimes { fmt.Println(nextTimes[i].Format(time.RFC1123)) // Output: