From ffcd470adf53f5983ff8ae1fefdcfb19f8f3ebd5 Mon Sep 17 00:00:00 2001 From: TowyTowy <85077986+TowyTowy@users.noreply.github.com> Date: Sat, 18 Jul 2026 18:55:17 +0200 Subject: [PATCH] fix(caldav): parse ISO 8601 week durations in reminder triggers (#3183) --- pkg/utils/duration.go | 13 +++++++------ pkg/utils/duration_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/pkg/utils/duration.go b/pkg/utils/duration.go index 576386246..8c228ac80 100644 --- a/pkg/utils/duration.go +++ b/pkg/utils/duration.go @@ -32,12 +32,13 @@ func ParseISO8601Duration(str string) time.Duration { years := parseDurationPart(matches[2], time.Hour*24*365) months := parseDurationPart(matches[3], time.Hour*24*30) - days := parseDurationPart(matches[4], time.Hour*24) - hours := parseDurationPart(matches[5], time.Hour) - minutes := parseDurationPart(matches[6], time.Second*60) - seconds := parseDurationPart(matches[7], time.Second) + weeks := parseDurationPart(matches[4], time.Hour*24*7) + days := parseDurationPart(matches[5], time.Hour*24) + hours := parseDurationPart(matches[6], time.Hour) + minutes := parseDurationPart(matches[7], time.Second*60) + seconds := parseDurationPart(matches[8], time.Second) - duration := years + months + days + hours + minutes + seconds + duration := years + months + weeks + days + hours + minutes + seconds if matches[1] == "-" { return -duration @@ -45,7 +46,7 @@ func ParseISO8601Duration(str string) time.Duration { return duration } -var durationRegex = regexp.MustCompile(`([-+])?P([\d\.]+Y)?([\d\.]+M)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`) +var durationRegex = regexp.MustCompile(`([-+])?P([\d\.]+Y)?([\d\.]+M)?([\d\.]+W)?([\d\.]+D)?T?([\d\.]+H)?([\d\.]+M)?([\d\.]+?S)?`) func parseDurationPart(value string, unit time.Duration) time.Duration { if len(value) != 0 { diff --git a/pkg/utils/duration_test.go b/pkg/utils/duration_test.go index e50cc293b..89ba9c2b8 100644 --- a/pkg/utils/duration_test.go +++ b/pkg/utils/duration_test.go @@ -34,6 +34,30 @@ func TestParseISO8601Duration(t *testing.T) { dur := ParseISO8601Duration("-P1DT1H1M1S") expected, _ := time.ParseDuration("-25h1m1s") + assert.Equal(t, expected, dur) + }) + t.Run("weeks", func(t *testing.T) { + dur := ParseISO8601Duration("P1W") + expected, _ := time.ParseDuration("168h") + + assert.Equal(t, expected, dur) + }) + t.Run("negative weeks", func(t *testing.T) { + dur := ParseISO8601Duration("-P2W") + expected, _ := time.ParseDuration("-336h") + + assert.Equal(t, expected, dur) + }) + t.Run("weeks combined with days", func(t *testing.T) { + dur := ParseISO8601Duration("P1W2D") + expected, _ := time.ParseDuration("216h") + + assert.Equal(t, expected, dur) + }) + t.Run("weeks combined with other units", func(t *testing.T) { + dur := ParseISO8601Duration("P1W2DT3H4M5S") + expected, _ := time.ParseDuration("219h4m5s") + assert.Equal(t, expected, dur) }) }