The Symmetry454 calendar
7 August 2026I recently went down something of a calendar reform rabbit hole. I’m not entirely sure how it started, but it ended with me being convinced that Dr Irv Bromberg’s Symmetry454 proposal is obviously the correct one: we can keep the 7 day week and 12 months that society is currently organised around, but changes the month lengths so you don’t need to stare at your fists or recite “30 days hath December”1 to remember how long they are. Every month (and so also every quarter and every year) starts on a Monday. This means that every (non-leap) year is the same, and you know that the sixth day of a month is always a Saturday, and the third Thursday of the month is always the 18th2. Dr Bromberg seems keen to point out that this means there would never be a Friday 13th.
The main downside, aside from the utter impracticality of actually changing calendar systems, is that the leap year rule is much more complicated3. It can’t be simplified by using the Gregorian “divisible by 4, unless divisible by 100, unless divisible by 400” rule, since a common year has 364 days and a leap year has a whole extra week instead of just a single day4.
Still, it’s fun to think about, and I have been experimenting in using Symmetry454 months for breaking up the year into more even chunks for planning: it’s nice to have a “September plan” that starts on a Monday, and each monthly plan is always a whole number of weeks.
Calendar programming
My first exploration of converting between the two calendars was nildei, a Haskell
program which reports today’s date in the Symmetry454 calendar, just
like date(1).
$ cabal run ; date
Fri Aug 12 12:52:39 AM BST 2026
Fri Aug 7 12:52:39 AM BST 2026
I didn’t bother to implement most of date(1), such as
custom formatting or showing a date other than today, so it’s not really
very useful unless you want to have it show the current time and date in
a status bar or something.
The algorithms are a kind of mash-up between those from the date arithmetic bible, Calendrical Calculations5, and the ones that are published on the Symmetry454 home page. In my other project, I ended up using Euclidean affine functions instead, but I wasn’t sure how to work them out for the Symmetry454 calendar, and the more naïve algorithms I ended up using are fast enough in practice.
As a follow-up, and to sharpen up my web programming chops while learning Svelte, I put together a little app to show the current Symmetry454 month and how it maps onto the corresponding Gregorian one. This one probably is a bit more useful, as far as tools for a calendar that nobody uses go. You can see when leap years are, check when each Symmetry454 month begins and ends, and figure out what your Symmetry454 birthday is.
Thoughts on Svelte
I’m not much of a web developer. I’ve done a tiny bit of React for some work projects, but I’ve spent more time on the backend and infrastructure sides of things, and I’m happy using a bit of vanilla JS to do basic things like nexton6music.
This was pretty much the first time I’ve set up a “modern” web
project from scratch to a more-or-less complete implementation. It’s
pretty bare-bones, with no persistent state, but I did enjoy using
Svelte. I remember React feeling very fragile, as I was never quite sure
that I’d remembered all the dependencies for useMemo,
useEffect and all the rest. I believe the compiler in
recent React versions makes this less painful, but I like the
explicitness of the $state and $derived
runes.
I spent more time faffing around with Flexbox and CSS Grid than wiring up the interactivity, which I think is an endorsement of Svelte. There were a few occasions where I was fighting it a little bit when I was trying to put Flexbox and Grid properties on child components in a natural way, but in the end it probably pushed me towards an overall better architecture where everything is more self-contained.
I started out using SvelteKit, but for such a simple application6 it just made the build more complicated for no benefit. I still don’t understand at all how Server Side Rendering and hydration work, but I’m going to continue not to worry about that until I really have to get my head around them.
The whole bundle comes in at 21.56 kB on the wire, 52.14 kB uncompressed, and I don’t really know how impressive that is. It gets me somewhere around the middle of the Green Team on the 512 KB Club, which I guess is decent enough without much effort. It loads quickly enough, and you can hold down the right arrow and scroll into the far future to your heart’s content. Something weird does occasionally start happening with the date arithmetic when you go far enough forwards or backwards in time, but it’s kind of fun for it to tell you that the Symmetric454 month of June -692 has random days of Gregorian January in the middle of it, so I’m not hugely invested in going through and converting all my arithmetic to use BigInt.
Now this is almost certainly not actually useful for anything, but I hope it might let you have fun celebrating the New Year on 4 January 2027 or tell people you are holding an event on 33 February. And, if nothing else, I now feel a bit more confident building reactive web applications.
I think that’s right?↩︎
without having to learn any tricks like the Doomsday rule, obviating another one of my little toy programs↩︎
There are a few different suggested leap rules, but the recommended one is
(52 × year + 146) % 293 < 52, which I definitely can’t work out in my head.↩︎This also means that there are 7 days in which someone can be in the Pirates of Penzance situation of having their birthday fall on a date that doesn’t happen most years. Dr Bromberg calculates that, in the Gregorian calendar, 97/146097 ≈ 0.066% of days are the 29th February, whereas 1/294 ≈ 0.34% of days fall in a leap week in the Symmetry454 calendar.↩︎
It’s a single page, but it’s not really an SPA. This seems silly.↩︎