This commit is contained in:
Erik Winter 2024-12-01 10:22:47 +01:00
parent 5b5ae5727d
commit 3f0bd4e047
2 changed files with 170 additions and 0 deletions

65
item/recur.go Normal file
View File

@ -0,0 +1,65 @@
package item
import "time"
type RecurPeriod string
const (
PeriodDay RecurPeriod = "day"
PeriodMonth RecurPeriod = "month"
)
type Recur struct {
Start time.Time
Period RecurPeriod
Count int
}
func (r *Recur) On(date time.Time) bool {
switch r.Period {
case PeriodDay:
return r.onDays(date)
case PeriodMonth:
return r.onMonths(date)
default:
return false
}
}
func (r *Recur) onDays(date time.Time) bool {
if r.Start.After(date) {
return false
}
testDate := r.Start
for {
if testDate.Equal(date) {
return true
}
if testDate.After(date) {
return false
}
dur := time.Duration(r.Count) * 24 * time.Hour
testDate = testDate.Add(dur)
}
}
func (r *Recur) onMonths(date time.Time) bool {
if r.Start.After(date) {
return false
}
tDate := r.Start
for {
if tDate.Equal(date) {
return true
}
if tDate.After(date) {
return false
}
y, m, d := tDate.Date()
tDate = time.Date(y, m+time.Month(r.Count), d, 0, 0, 0, 0, time.UTC)
}
}

105
item/recur_test.go Normal file
View File

@ -0,0 +1,105 @@
package item_test
import (
"testing"
"time"
"go-mod.ewintr.nl/planner/item"
)
func TestRecur(t *testing.T) {
t.Parallel()
t.Run("days", func(t *testing.T) {
r := item.Recur{
Start: time.Date(2024, 12, 1, 0, 0, 0, 0, time.UTC),
Period: item.PeriodDay,
Count: 5,
}
day := 24 * time.Hour
for _, tc := range []struct {
name string
date time.Time
exp bool
}{
{
name: "before",
date: time.Date(202, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
name: "start",
date: r.Start,
exp: true,
},
{
name: "after true",
date: r.Start.Add(15 * day),
exp: true,
},
{
name: "after false",
date: r.Start.Add(16 * day),
},
} {
t.Run(tc.name, func(t *testing.T) {
if act := r.On(tc.date); tc.exp != act {
t.Errorf("exp %v, got %v", tc.exp, act)
}
})
}
})
t.Run("months", func(t *testing.T) {
r := item.Recur{
Start: time.Date(2021, 2, 3, 0, 0, 0, 0, time.UTC),
Period: item.PeriodMonth,
Count: 3,
}
for _, tc := range []struct {
name string
date time.Time
exp bool
}{
{
name: "before start",
date: time.Date(2021, 1, 27, 0, 0, 0, 0, time.UTC),
},
{
name: "on start",
date: time.Date(2021, 2, 3, 0, 0, 0, 0, time.UTC),
exp: true,
},
{
name: "8 weeks after",
date: time.Date(2021, 3, 31, 0, 0, 0, 0, time.UTC),
},
{
name: "one month",
date: time.Date(2021, 3, 3, 0, 0, 0, 0, time.UTC),
},
{
name: "3 months",
date: time.Date(2021, 5, 3, 0, 0, 0, 0, time.UTC),
exp: true,
},
{
name: "4 months",
date: time.Date(2021, 6, 3, 0, 0, 0, 0, time.UTC),
},
{
name: "6 months",
date: time.Date(2021, 8, 3, 0, 0, 0, 0, time.UTC),
exp: true,
},
} {
t.Run(tc.name, func(t *testing.T) {
if act := r.On(tc.date); tc.exp != act {
t.Errorf("exp %v, got %v", tc.exp, act)
}
})
}
})
}