A Fast 64-Bit Date Algorithm (30–40% faster by counting dates backwards)
42 comments
·November 23, 2025kccqzy
zokier
not completely coincidentally, March was also the first month of the year in many historical calendars. Afaik that also explains why the month names have offset to them (sept, oct, nov, dec)
edit: I just love that there are like 5 different comments pointing out this same thing
Mikhail_Edoshin
I've read that not only March was the first month, but the number of months was only ten: winter months did not need to be counted because there was no agricultural work to be done (which was the primary purpose of the calendar). So after the tenth month there was a strange unmapped period.
_dain_
>So after the tenth month there was a strange unmapped period.
this is when time-travelling fugitives hide out
null
Izikiel43
> explains why the month names have offset to them (sept, oct, nov, dec)
Everything now makes sense, I always wondered why September was the nine month with a 7 prefix.
silisili
At this risk of me feeling stupid, could you briefly explain the benefit of this?
kccqzy
I just added a link to the code with a brief comment. Basically, it simplifies the leap year date calculation. If February is the last month of the year, then the possibly-existing leap day is the last day of the year. If you do it the normal way your calculations for March through December need to know whether February is a leap year. Now none of that is needed. You don’t even need explicit code to calculate whether a given year is a leap year: it’s implicit in the constants 146097, 36524, and 1461.
zamadatix
The magic numbers at the end of this explanation are the number of days of each part of the leap year cycle:
146097 days = 400 year portion of the leap year cycles (including leap years during that)
36524 days = same for the 100 year portion of the leap year cycles
1461 days = 4 year cycle + 1 leap day
d--b
IIRC, it's also why the leap day was set to Feb 29th in the first place. At the time (romans?) the year started March 1st.
In case someone was wondering why in the world someone said we should add a day to the second month of the year...
zimpenfish
As well as the leap year stuff people have mentioned, there was something else that I've got a vague memory of (from an old SciAm article, IIRC, which was about using March as the first month for calculations) which pointed out that if you use March as 0, you can multiple the month number by (I forget exactly what but it was around 30.4ish?) and, if you round the fraction up, you get the day number of the start of that month and it all works out correctly for the right 31-30-31 etc sequence.
da_chicken
It's easy to know what day of the year it is because leap days are at the end.
3eb7988a1663
Not so relevant, but some fun history, the Roman calendar did start in March, so tacking on the leap years was done at the finale. This also meant that the root of the words - the "oct" in october means 8 was also the eighth month of the year.
null
benjoffe
A write-up of a new Gregorian date conversion algorithm.
It achieves a 30–40% speed improvement on x86-64 and ARM64 (Apple M4 Pro) by reversing the direction of the year count and reducing the operation count (4 multiplications instead of the usual 7+).
Paper-style explanation, benchmarks on multiple architectures, and full open-source C++ implementation.
sltkr
Very cool algorithm and great write-up!
I was a bit confused initially about what your algorithm actually did, until I got to the pseudo-code. Ideally there would be a high level description of what the algorithm is supposed to do before that.
Something as simple as: “a date algorithm converts a number of days elapsed since the UNIX epoch (1970-01-01) to a Gregorian calendar date consisting of day, month, and year” would help readers understand what they're about to read.
digitalPhonix
Very nice writeup!
> Years are calculated backwards
How did that insight come about?
drob518
Nicely done.
zX41ZdbW
Interesting how it compares with the ClickHouse implementation, which uses a lookup table: https://github.com/ClickHouse/ClickHouse/blob/master/src/Com...
So that a day number can be directly mapped to year, month, and day, and the calendar date can be mapped back with a year-month LUT.
ComputerGuru
Good opportunity to plug this folklore legend: https://neosmart.net/forums/threads/an-extended-history-of-t...
Findecanor
TIL that Unix Time does not count leap seconds. If it did, it wouldn't have been possible to write routines that are this fast.
pyrolistical
For something this short that is pure math, why not just hand write asm for the most popular platforms? Prevents compiler from deoptimizing in the future.
Have a fallback with this algorithm for all other platforms.
swiftcoder
Nice to see the micro-optimising folks are still making progress on really foundational pieces of the programming stack
HackingWizard
Yes, some sharing Vibe coded slop.
juancn
It took me a while to understand that internally it uses 128bit numbers, that `>> 64` in the pseudocode was super confusing until I saw the C++ code.
Neat code though!
zkmon
Nice to see that there are still some jewels left to be dug out from the algorithm land.
masfuerte
The Windows epoch starts on 1601-01-01. I always assumed that was because it slightly simplifies the calculation, as described in the article. But it's not as good as the article's method of counting backwards.
null
kittikitti
Thank you for sharing. This is a great achievement not only in the ability to invent a novel algorithm with significant performance gains but also the presentation of the work. It's very thorough and detailed, and I appreciated reading it.
I wrote my own date calculation functions a while ago. And during that, I had an aha moment to treat March 1 as the beginning of the year during internal calculations[0]. I thought it was a stroke of genius. It turns out this article says that’s the traditional way.
[0]: https://github.com/kccqzy/smartcal/blob/9cfddf7e85c2c65aa6de...