On Sat, Sep 24, 2022 at 1:17 AM Ted Phelps via tz <tz@iana.org> wrote:
On 2022-09-24, Tony Finch wrote:
> You might also like https://dotat.at/@/2008-09-10-counting-the-days.html
> (That does things the hard way, rather than relying on tm_yday)
> and https://dotat.at/@/2008-09-15-the-date-of-the-count.html

Wow, that's some clever math you've done there; far nicer than the
clumsy approach I'd used to canonicalize the year, month and day.  It's
a little slower than my clumsy approach in the case where the year,
month and day are already in canonical form, but can be much faster when
they're not.  I'll incorporate those changes into my git project in the
coming days, thank you!

static inline int64_t daynum(int64_t year, int mon, int day)
{
    // Rotate the start of the year to March so that the troublesome
    // leap day is last.  Also, make March month number 4 to simplify
    // the calculation below.
    if (mon > 2) {
        mon += 1;
    } else {
        mon += 13;
        year -= 1;
    }

    // Compute the day number since the start of year 1.  This clever
    // expression is thanks to Tony Finch; see his blog post for a
    // detailed explanation of what's going on here:
    //     https://dotat.at/@/2008-09-10-counting-the-days.html
    return year * 1461 / 4 - year / 100 + year / 400 + mon * 153 / 5 + day - 428;
}


Assuming we want to model the proleptic Gregorian calendar, it would be nice if the output was linear over all inputs.  At the moment, for example, daynum(0, 2, 29) and daynum(0, 3, 1) both return -305.