diff --git a/voussoir.net/eternalseptember/eternalseptember.html b/voussoir.net/eternalseptember/eternalseptember.html
new file mode 100644
index 0000000..1531d08
--- /dev/null
+++ b/voussoir.net/eternalseptember/eternalseptember.html
@@ -0,0 +1,41 @@
+
+
+ eternalseptember
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/voussoir.net/eternalseptember/eternalseptember.js b/voussoir.net/eternalseptember/eternalseptember.js
new file mode 100644
index 0000000..c7b81e5
--- /dev/null
+++ b/voussoir.net/eternalseptember/eternalseptember.js
@@ -0,0 +1,121 @@
+const eternalseptember = {};
+
+eternalseptember.EPOCH = new Date("1993-09-01T00:00:00");
+
+eternalseptember.AM_PM = ["AM", "PM"];
+eternalseptember.WEEKDAY_NAMES = [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+]
+eternalseptember.WEEKDAY_ABBREVS = [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+]
+eternalseptember.MONTH_NAMES = [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+]
+
+eternalseptember.twelvehour =
+function twelvehour(hour)
+{
+ hour = parseInt(hour % 12);
+ if (hour === 0)
+ {
+ return 12;
+ }
+ return hour;
+}
+eternalseptember.strftime =
+function strftime(date, format)
+{
+ const diff = date - eternalseptember.EPOCH;
+ const diff_days = parseInt(diff / (1000*60*60*24));
+
+ const day_of_month = diff_days + 1
+ const day_of_year = diff_days + 244
+
+ let result = format;
+ result = result.replace(/(? 12)]);
+ return result;
+}
+
+eternalseptember.init_clock =
+function init_clock(clock)
+{
+ const format = clock.dataset.eternalseptemberStrftime;
+ if (clock.dataset.eternalseptemberTickrate === undefined)
+ {
+ clock.innerText = eternalseptember.strftime(new Date(), format);
+ return;
+ }
+
+ const tickrate = parseInt(clock.dataset.eternalseptemberTickrate);
+ const ticktock = function ticktock()
+ {
+ clock.innerText = eternalseptember.strftime(new Date(), format);
+ setTimeout(ticktock, tickrate);
+ }
+ ticktock();
+}
+
+eternalseptember.init_clocks =
+function init_clocks()
+{
+ const clocks = Array.from(document.getElementsByClassName("eternalseptember_clock"));
+ for (const clock of clocks)
+ {
+ eternalseptember.init_clock(clock);
+ }
+}
+
+eternalseptember.on_pageload =
+function on_pageload()
+{
+ eternalseptember.init_clocks();
+}
+document.addEventListener("DOMContentLoaded", eternalseptember.on_pageload);
diff --git a/voussoir.net/index.html b/voussoir.net/index.html
index ce346c6..5fe5e6c 100644
--- a/voussoir.net/index.html
+++ b/voussoir.net/index.html
@@ -393,6 +393,8 @@ code { font-family: monospace; }
FFmpeg logo
Git logo
Derivative artwork based on Reddit's classic Snoo mascot
+
+