Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix signedness bug #19

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Fix signedness bug #19

wants to merge 2 commits into from

Conversation

userx14
Copy link

@userx14 userx14 commented Oct 26, 2021

this fixes calculation for all years < 1200.

this fixes calculation for all years < 1200.
@userx14
Copy link
Author

userx14 commented Oct 26, 2021

When testing with dates < 1200 one will encounter a bug which results in the wrong unix timestamps being generated:

struct TM dateOfYearZero = {.tm_year = -1900, .tm_mday = 1};
Time64_T testUnixTime = mktime64(&dateOfYearZero);
printf("%s", ctime64(&testUnixTime));

without the bugfix:
Fri Jan 19 00:00:00 -3199

with the bugfix
Sat Jan 1 00:00:00 0

@barefootcoder
Copy link

I'm not sure I have authorization to release this—I'm not even 100% sure I know how to build/test it, to be honest—but I'd feel a lot more comfortable about trying if you could add a test for it to your merge request.

Thx for your contribution!

@userx14
Copy link
Author

userx14 commented Nov 20, 2021

@barefootcoder thanks for the suggestion,

while trying to write unit tests I found one more issue with the function:
Even with the current fix the function seconds_between_years is not symmertic in it's arguments, meaning that seconds_between_years(2000, 2401) != (-1)* seconds_between_years(2401, 2000).

With my first commit ("Fix signedness bug") the difference is only one day though.

The reason for this seems to be that the function in one case counts the leap years upward starting from 2000 and skips 2401, while in the other case it starts from 2401 and skips 2000. I think that the one that skips the larger year is the correct behavior, but I'm not 100% certain on that. I modified the function such that in both cases this is the behavior.

Since thinking about which of the years on the edge of the interval is quiet tricky I would be grateful if someone could verify my calculations for the leap years between 0 and 1901 or check some negative dates. There is a chance that the second_between_years should instead consider the lowest provided year and no the highest one and that it was intended behavoir.

Best, Benjamin

@userx14
Copy link
Author

userx14 commented Nov 20, 2021

Oh no, I think it's even more complicated:

The right year in the only usage of this function is passed through safe_year() which ensures that both years satisfy

y2038/time64.c

Lines 345 to 347 in c17a49a

A matching year...
1) Starts on the same day of the week.
2) Has the same leap year status.

, so it matches the left year in it's number of days. Leaving out the first instead of the last year in the iteration should not make a difference this way.

The function was probably designed in such a way that it is only able to give the correct result for years that satisfy this requirement, such that it does not matter if one skips the first or last year. Maybe one could rename the function from seconds_between_years to something like second_between_years_with_same_num_days or add a comment.

But that also means that the tests for this function like

is_Int64( seconds_between_years( (Year)2001, (Year)2000 ),

can not be written as straightfoward as one might think.
The dates with which the function can be tested must either both be leap years or both be normal years. Some of the current tests do not satisfy this requirement, but still work because the iteration direction was starting from the lower year 2000:

y2038/time64.c

Lines 531 to 532 in c17a49a

seconds += length_of_year[IS_LEAP_ABS(right_year)] * 60 * 60 * 24;
right_year++;

I think the solution of this will take some time...

Best, Benjamin

@userx14
Copy link
Author

userx14 commented Nov 20, 2021

Tests should be fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants