diff options
Diffstat (limited to 'time')
-rw-r--r-- | time/time.go | 44 | ||||
-rw-r--r-- | time/time_test.go | 68 |
2 files changed, 112 insertions, 0 deletions
diff --git a/time/time.go b/time/time.go new file mode 100644 index 0000000..97bd3d5 --- /dev/null +++ b/time/time.go @@ -0,0 +1,44 @@ +// Copyright © 2022 siddharth ravikumar <s@ricketyspace.net> +// SPDX-License-Identifier: ISC + +// ISO 8601 utility functions +package time + +import ( + "fmt" + "regexp" + "strconv" +) + +// ISO 8601 Duration regex for matching duration in PT3H4M60S format. +var durationRegex = regexp.MustCompile(`PT(([0-9]{0,2})?H)?(([0-9]{0,2})?M)?(([0-9]{0,2}?)S)?`) + +// Converts ISO 8601 duration[1] to seconds. +// +// Recognizes durations in this format: PT3H4M60S +// +// [1]: https://en.wikipedia.org/wiki/ISO_8601#Durations +func durationToSeconds(duration string) (int, error) { + m := durationRegex.FindStringSubmatch(duration) + if m == nil || len(m) == 0 { + return 0, fmt.Errorf("duration invalid: %v", duration) + } + hours, err := strconv.Atoi(m[2]) + if err != nil { + hours = 0 + } + mins, err := strconv.Atoi(m[4]) + if err != nil { + mins = 0 + } + secs, err := strconv.Atoi(m[6]) + if err != nil { + secs = 0 + } + + // Add 'em all together. + secs += hours * 3600 + secs += mins * 60 + + return secs, nil +} diff --git a/time/time_test.go b/time/time_test.go new file mode 100644 index 0000000..d55783e --- /dev/null +++ b/time/time_test.go @@ -0,0 +1,68 @@ +// Copyright © 2022 siddharth ravikumar <s@ricketyspace.net> +// SPDX-License-Identifier: ISC + +package time + +import "testing" + +func TestDurationToSeconds(t *testing.T) { + secs, err := durationToSeconds("PT3H4M60S") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 11100 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } + + secs, err = durationToSeconds("PT4M60S") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 300 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } + + secs, err = durationToSeconds("PT12H") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 43200 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } + + secs, err = durationToSeconds("PT1H") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 3600 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } + + secs, err = durationToSeconds("PT2H") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 7200 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } + + secs, err = durationToSeconds("PT45M") + if err != nil { + t.Errorf("failed: %v", err) + return + } + if secs != 2700 { + t.Errorf("duration in seconds incorrect: %v", secs) + return + } +} |