recur every n months
This commit is contained in:
parent
9f9934ef97
commit
2ea3639505
|
@ -201,6 +201,10 @@ func (d Date) Weekday() time.Weekday {
|
||||||
return d.t.Weekday()
|
return d.t.Weekday()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d Date) Day() int {
|
||||||
|
return d.t.Day()
|
||||||
|
}
|
||||||
|
|
||||||
func (d Date) Add(days int) Date {
|
func (d Date) Add(days int) Date {
|
||||||
year, month, day := d.t.Date()
|
year, month, day := d.t.Date()
|
||||||
return NewDate(year, int(month), day+days)
|
return NewDate(year, int(month), day+days)
|
||||||
|
|
|
@ -195,13 +195,13 @@ func TestDateString(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "normal",
|
name: "normal",
|
||||||
date: task.NewDate(2021, 1, 30),
|
date: task.NewDate(2021, 5, 30),
|
||||||
exp: "2021-01-30 (saturday)",
|
exp: "2021-05-30 (sunday)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "normalize",
|
name: "normalize",
|
||||||
date: task.NewDate(2021, 1, 32),
|
date: task.NewDate(2021, 5, 32),
|
||||||
exp: "2021-02-01 (monday)",
|
exp: "2021-06-01 (tuesday)",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
|
|
@ -37,6 +37,9 @@ func NewRecurrer(recurStr string) Recurrer {
|
||||||
if recur, ok := ParseEveryNWeeks(start, terms); ok {
|
if recur, ok := ParseEveryNWeeks(start, terms); ok {
|
||||||
return recur
|
return recur
|
||||||
}
|
}
|
||||||
|
if recur, ok := ParseEveryNMonths(start, terms); ok {
|
||||||
|
return recur
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -191,7 +194,7 @@ type EveryNWeeks struct {
|
||||||
|
|
||||||
// yyyy-mm-dd, every 3 weeks
|
// yyyy-mm-dd, every 3 weeks
|
||||||
func ParseEveryNWeeks(start Date, terms []string) (Recurrer, bool) {
|
func ParseEveryNWeeks(start Date, terms []string) (Recurrer, bool) {
|
||||||
if len(terms) < 1 || len(terms) > 1 {
|
if len(terms) != 1 {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,3 +228,41 @@ func (enw EveryNWeeks) RecursOn(date Date) bool {
|
||||||
func (enw EveryNWeeks) String() string {
|
func (enw EveryNWeeks) String() string {
|
||||||
return fmt.Sprintf("%s, every %d weeks", enw.Start.String(), enw.N)
|
return fmt.Sprintf("%s, every %d weeks", enw.Start.String(), enw.N)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EveryNMonths struct {
|
||||||
|
Start Date
|
||||||
|
N int
|
||||||
|
}
|
||||||
|
|
||||||
|
// yyyy-mm-dd, every 3 months
|
||||||
|
func ParseEveryNMonths(start Date, terms []string) (Recurrer, bool) {
|
||||||
|
if len(terms) != 1 {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
terms = strings.Split(terms[0], " ")
|
||||||
|
if len(terms) != 3 || terms[0] != "every" || terms[2] != "months" {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
n, err := strconv.Atoi(terms[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return EveryNMonths{
|
||||||
|
Start: start,
|
||||||
|
N: n,
|
||||||
|
}, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enm EveryNMonths) RecursOn(date Date) bool {
|
||||||
|
if enm.Start.After(date) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return enm.Start.Day() == date.Day()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enm EveryNMonths) String() string {
|
||||||
|
return fmt.Sprintf("%s, every %d months", enm.Start.String(), enm.N)
|
||||||
|
}
|
||||||
|
|
|
@ -300,3 +300,50 @@ func TestEveryNWeeks(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEveryNMonths(t *testing.T) {
|
||||||
|
everyNMonths := task.EveryNMonths{
|
||||||
|
Start: task.NewDate(2021, 2, 3),
|
||||||
|
N: 3,
|
||||||
|
}
|
||||||
|
everyNMonthsStr := "2021-02-03 (wednesday), every 3 months"
|
||||||
|
|
||||||
|
t.Run("parse", func(t *testing.T) {
|
||||||
|
test.Equals(t, everyNMonths, task.NewRecurrer(everyNMonthsStr))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("string", func(t *testing.T) {
|
||||||
|
test.Equals(t, everyNMonthsStr, everyNMonths.String())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("recurs on", func(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
date task.Date
|
||||||
|
exp bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "before start",
|
||||||
|
date: task.NewDate(2021, 1, 27),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "on start",
|
||||||
|
date: task.NewDate(2021, 2, 3),
|
||||||
|
exp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "8 weeks after",
|
||||||
|
date: task.NewDate(2021, 3, 31),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "one month",
|
||||||
|
date: task.NewDate(2021, 3, 3),
|
||||||
|
exp: true,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
test.Equals(t, tc.exp, everyNMonths.RecursOn(tc.date))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue