summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--time/time.go44
-rw-r--r--time/time_test.go68
3 files changed, 113 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 29e5762..6dd8753 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
# Copyright © 2022 siddharth ravikumar <s@ricketyspace.net>
MOD=ricketyspace.net/peach
-PKGS=${MOD}/cache ${MOD}/client ${MOD}/nws ${MOD}/photon
+PKGS=${MOD}/cache ${MOD}/client ${MOD}/nws ${MOD}/photon ${MOD}/time
CSS=static/peach.min.css
peach: vet fix fmt ${CSS}
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
+ }
+}