Hello Cassio,
thanks for your input.
On Tue, Jun 10, 2025 at 09:31:48PM +0100, Cassio Neri wrote:
Although untested, I'm pretty sure that with very small changes, the previous revision (1d1bb12) can handle dates prior to 1970-01-01 with no need to add extra branches or arithmetic operations. Indeed, 1d1bb12 contains:
<code> /* time must be positive */ days = div_s64_rem(time, 86400, &secs);
/* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7;
/* long comments */
udays = ((u32) days) + 719468;
</code>
This could have been changed to:
<code> /* time must be >= -719468 * 86400 which corresponds to 0000-03-01 */ udays = div_u64_rem(time + 719468 * 86400, 86400, &secs);
/* day of the week, 0000-03-01 was a Wednesday (in the proleptic Gregorian calendar) */ tm->tm_wday = (days + 3) % 7;
/* long comments */
</code>
Indeed, the addition of 719468 * 86400 to `time` makes `days` to be 719468 more than it should be. Therefore, in the calculation of `udays`, the addition of 719468 becomes unnecessary and thus, `udays == days`. Moreover, this means that `days` can be removed altogether and replaced by `udays`. (Not the other way around because in the remaining code `udays` must be u32.)
Now, 719468 % 7 = 1 and thus tm->wday is 1 day after what it should be and we correct that by adding 3 instead of 4.
Therefore, I suggest these changes on top of 1d1bb12 instead of those made in 7df4cfe. Since you're working on this, can I please kindly suggest two other changes?
It's to late for "instead", and we're discussing a backport to stable for a commit that is already in v6.16-rc1. While your concerns are correct (though I didn't check the details yet), I claim that 7df4cfef8b35 is correct and it's the right thing to backport that today. Incremental changes can then go in the development version (and backported if deemed necessary).
- Change the reference provided in the long comment. It should say, "The
following algorithm is, basically, Figure 12 of Neri and Schneider [1]" and [1] should refer to the published article:
Neri C, Schneider L. Euclidean affine functions and their application to calendar algorithms. Softw Pract Exper. 2023;53(4):937-970. doi: 10.1002/spe.3172 https://doi.org/10.1002/spe.3172
The article is much better written and clearer than the pre-print currently referred to.
I'll add that to my todo list. (that = improving rtc_time64_to_tm() and reading your paper :-)
- Function rtc_time64_to_tm_test_date_range in drivers/rtc/lib_test.c, is
a kunit test that checks the result for everyday in a 160000 years range starting at 1970-01-01. It'd be nice if this test is adapted to the new code and starts at 1900-01-01 (technically, it could start at 0000-03-01 but since tm->year counts from 1900, it would be weird to see tm->year == -1900 to mean that the calendar year is 0.) Also 160000 is definitely an overkill (my bad!) and a couple of thousands of years, say 3000, should be more than safe for anyone. :-)
I already did 2), see https://git.kernel.org/linus/ccb2dba3c19f.
Best regards Uwe