hswaw/site: add calendar/event library

This will let us populate upcoming events server-side on the website (or
serve this data in a format that can be more easily consumed by JS).

Change-Id: I0f6b5bf9831f4d07acebb4eb77a7d88b63fe8e46
diff --git a/hswaw/site/calendar/event_test.go b/hswaw/site/calendar/event_test.go
new file mode 100644
index 0000000..1e95306
--- /dev/null
+++ b/hswaw/site/calendar/event_test.go
@@ -0,0 +1,73 @@
+package calendar
+
+import (
+	"fmt"
+	"testing"
+	"time"
+)
+
+func TestWarsawDate(t *testing.T) {
+	makeTime := func(s string) EventTime {
+		t.Helper()
+		warsaw, err := time.LoadLocation("Europe/Warsaw")
+		if err != nil {
+			t.Fatalf("could not get Warsaw timezone: %v", err)
+		}
+		ti, err := time.ParseInLocation("2006/01/02 15:04", s, warsaw)
+		if err != nil {
+			t.Fatal("could not parse test time %q: %v", s, err)
+		}
+		return EventTime{
+			Time: ti,
+		}
+	}
+	makeDay := func(s string) EventTime {
+		t.Helper()
+		ti, err := time.Parse("2006/01/02", s)
+		if err != nil {
+			t.Fatal("could not parse test day %q: %v", s, err)
+		}
+		return EventTime{
+			Time:     ti,
+			WholeDay: true,
+		}
+	}
+	for i, te := range []struct {
+		start EventTime
+		end   EventTime
+		want  string
+	}{
+		{
+			makeTime("2021/03/14 13:37"), makeTime("2021/04/20 21:37"),
+			"2021/03/14 13:37 - 2021/04/20 21:37",
+		},
+		{
+			makeTime("2021/04/20 13:37"), makeTime("2021/04/20 21:37"),
+			"2021/04/20 13:37 - 21:37",
+		},
+		{
+			makeDay("2021/06/01"), makeDay("2021/07/01"),
+			"2021/06/01 - 30",
+		},
+		{
+			makeDay("2021/03/14"), makeDay("2021/04/21"),
+			"2021/03/14 - 2021/04/20",
+		},
+		{
+			makeDay("2021/04/20"), makeDay("2021/04/21"),
+			"2021/04/20",
+		},
+	} {
+		te := te
+		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+			ev := UpcomingEvent{
+				Start: &te.start,
+				End:   &te.end,
+			}
+			got := ev.WarsawDate()
+			if got != te.want {
+				t.Fatalf("wanted %q, got %q", te.want, got)
+			}
+		})
+	}
+}