"Why is day of the month 1-indexed but the month is 0-indexed in C?"<p>This Twitter thread from November 2020[1] and its HackerNews discussion[2] seem relevant.<p>1: <a href="https://twitter.com/hillelogram/status/1329228419628998665" rel="nofollow">https://twitter.com/hillelogram/status/1329228419628998665</a><p>2: <a href="https://news.ycombinator.com/item?id=25195287" rel="nofollow">https://news.ycombinator.com/item?id=25195287</a>
At least in Perl, the rationale for this (apart from copying C) is that it's very easy to reference a list (array) of month names if the month indices are zero-based.
Zero-based months is awkward when printing as a number, but convenient when indexing an array:<p><pre><code> const MONTHS = ["Jan", "Feb", "Mar", ..., "Dec"];
console.log(MONTHS[d.getMonth()]);</code></pre>
The same justification exists in JS (where it's copied from Java which copies it from C). However, interestingly checking the FORTRAN IV specification documents for the PDP-10, it's not implemented as a 3 letter ASCII abbreviation. That document dates to 1975, I don't know if I can find if the date exists in the first version of the document, which should date to 1967. I was unable to find a reference to a builtin in the base FORTRAN II, which only provides 20 builtin functions, date not making the list. I think newer versions of FORTRAN77 has idate which is 1-indexed but I couldn't find it in the older standard listed on wg5's specification documents.<p>[^1]: <a href="https://github.com/PDP-10/f40/tree/master/doc" rel="nofollow">https://github.com/PDP-10/f40/tree/master/doc</a>
I think it all comes down to whether you're counting elements as the primary goal. However, months are poorly defined relative to something like an astronomical year or a standard day, so they're more like objects. That is to say, adding different months doesn't give you the same number of days as a result.<p>Hence, dealing with months is perhaps a bit more like indexing variable-sized objects, and for that purpose traditionally, the array-of-pointers approach uses zero-based pointer arithmetic, which is what the designers might have been thinking.<p>Really however, the months should probably be treated more like structs, with the number of days in that month being a data member. This would allow sanity checks, i.e. entering Feb 30 should raise an error, but not May 30.
I think it's important to be able to work with mod(%) 12 for some operations on year <--> month relationship. All years have 12 months. For day of the month you need additional logic to handle diferent lengths... and other issues.