In belated honor of 2024 being a leap year, here's a story about how I learned 2011 was not a leap year, ISO 8601, proleptic Gregorian calendars and forking Node.
To belatedly commemorate the leap year of 2024, here is a story about how I discovered of 2011 wasn't a leap year, dove into the intricacies of ISO 8601, the concept of proleptic Gregorian calendars, and decided to fork Node on a whim.
- Understanding the Proleptic Gregorian Calendar
- 11ty and leap years
- Apple, NSCalendar and sticklers for reality
- Let's fork Node!
Understanding the Proleptic Gregorian Calendar
The Gregorian calendar is more or less the calendar system we all use today and was established on Friday, October 15th, 1582. The curious thing about this is that it came immediately after Thursday, October 4th. They had to do this to synchronize with the switch from the Julian calendar. As are a result, those ten days never happened.
The proleptic Gregorian calendar attempts to make this less confusing by basically pretending the Gregorian calendar has always been in use. In this world, when looking back at dates that happened prior to the switch, a date like October 7th, 1582 can exist. This is a modern convention to help with historical consistency.
new Date("October 11 1582")
new Date("October 33 1979")
// Invalid Date
But it doesn't care about all the days that could never happen:
new Date("February 31 2024")
It doesn't throw an
Invalid Date even thought February 31 could never possibly exist. It's actually returning March 2nd, 2024 in this example!
If you dive in the source you can see it takes a (somewhat lazy) assumption by checking the days first and assuming 1 to 31 can always be valid. It then checks the month to see if it has that many days. Instead of throwing an error if it doesn't, it just substracts the max number of days from that month and uses the remainder to figure out which day it is in the next month.
11ty and leap years
Something funny happened when I resurrected some old blog posts from 2011. The tool I use to build this site (11ty) started throwing errors. I assumed there was some weird piece of misformatted metadata in one of the posts, but what I found was a lot stranger.
The offending post was written on February 29th, 2011. It turns out that day never existed—it's only a leap year if it is divisible by 4, except for end-of-century years which must be divisible by 400.
In a nut-shell, because I'd written this date down wrong over a decade ago, and because something in 11ty is a stickler for real dates, I had to change the date to fix my blog. The funny part is I had no way of knowing, 10+ years later, if I'd actually written it on March 1st or February 28th.
Apple, NSCalendar and sticklers for reality
It makes sense to me that the company whose founder gave so much thought about typography in early computing would take the time to put thought into their standard calendar class to account for the Julian to Gregorian transition in a more nuanced and historically-accurate way.
One of the more fun macOS easter eggs live sin the Calendar app. If you go back to October 1582 you can see Thursday, October 4th immediately followed by Friday, October 15th.
Let's fork Node!
I like the way NSCalendar handles this situation better. So I did what any sensible person would do: I dusted off my C++ brain and forked Node.
I'd never built Node from scratch, let alone fork an entire language just to make such a silly, opinionated tweak to a standard model. The documentation is clear though, and the project is soundly structured. After some hunting, pecking and reading I found the place to introduce my change:
If you've found any of this nonsense helpful or intriguing—and particularly if you have your own silly explorations to share—please feel free to reach out! I love a good goofy deep-dive into the inane.