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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 37 additions & 19 deletions t/seconds_between_years.t.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,54 @@
#define SECS_PER_LEAP (SECS_PER_DAY * 366LL)

int main(void) {
is_Int64( seconds_between_years( (Year)2000, (Year)2000 ),



/*tests inside the save year range*/
/*both tested years are the same year*/
is_Int64( seconds_between_years_with_same_daycount( (Year)2000, (Year)2000 ),
0LL,
"2000 - 2000"
);

is_Int64( seconds_between_years( (Year)2001, (Year)2000 ),
SECS_PER_LEAP,
"2001 - 2000"
/*both years are leap years since they are ​divisible by 4,100 and 400*/
is_Int64( seconds_between_years_with_same_daycount( (Year)2004, (Year)2000 ),
SECS_PER_LEAP + 3 * SECS_PER_YEAR,
"2004 - 2000"
);

is_Int64( seconds_between_years( (Year)2004, (Year)2000 ),
/*both years are non leap years because they are not ​divisible by 4*/
is_Int64( seconds_between_years_with_same_daycount( (Year)2005, (Year)2001 ),
SECS_PER_YEAR * 3 + SECS_PER_LEAP,
"2004 - 2000"
"2005 - 2001"
);

is_Int64( seconds_between_years( (Year)2005, (Year)2000 ),
SECS_PER_YEAR * 3 + SECS_PER_LEAP * 2,
"2005 - 2000"
);

is_Int64( seconds_between_years( (Year)2400, (Year)2000 ),
SECS_PER_YEAR * 303 + SECS_PER_LEAP * 97,
"2400 - 2000"
);

is_Int64( seconds_between_years( (Year)2401, (Year)2000 ),
SECS_PER_YEAR * 303 + SECS_PER_LEAP * 98,
"2401 - 2000"
/*tests with left_year in the future beyond the safe year range*/
/*both years are leap years since they are divisible by 4,100 and 400*/
is_Int64( seconds_between_years_with_same_daycount( (Year)2800, (Year)2000 ),
SECS_PER_YEAR * 606 + SECS_PER_LEAP * 194,
"2800 - 2000"
);
/*both years are non leap years because they are not divisible by 4*/
is_Int64( seconds_between_years_with_same_daycount( (Year)2801, (Year)2001 ),
SECS_PER_YEAR * 606 + SECS_PER_LEAP * 194,
"2801 - 2001"
);



/*tests with left_year in the past before the safe year range*/
/*both years are leap years since they are divisible by 4,100 and 400*/
is_Int64( seconds_between_years_with_same_daycount( (Year)1200, (Year)2000 ),
(-1) * (SECS_PER_YEAR * 606 + SECS_PER_LEAP * 194),
"1200 - 2000"
);
/*both years are non leap years because they are not divisible 4*/
is_Int64( seconds_between_years_with_same_daycount( (Year)1201, (Year)2001 ),
(-1) * (SECS_PER_YEAR * 606 + SECS_PER_LEAP * 194),
"1201 - 2001"
);

done_testing();
return 0;
}
9 changes: 5 additions & 4 deletions time64.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,9 @@ struct tm * fake_gmtime_r(const time_t *time, struct tm *result) {

#endif /* #ifndef HAS_GMTIME_R */


static Time64_T seconds_between_years(Year left_year, Year right_year) {
/* left_year and right_year must have the same number of days (both 365 or both 366)*/
/* right_year must be inside the safe date range*/
static Time64_T seconds_between_years_with_same_daycount(Year left_year, Year right_year) {
int increment = (left_year > right_year) ? 1 : -1;
Time64_T seconds = 0;
Year cycles;
Expand All @@ -521,7 +522,7 @@ static Time64_T seconds_between_years(Year left_year, Year right_year) {
else if( left_year < 1600 ) {
TIME64_TRACE1("year %"PRId64" < 1600\n", left_year);
cycles = (left_year - 1600) / 400;
left_year += cycles * 400;
left_year -= cycles * 400;
seconds += cycles * seconds_in_gregorian_cycle;
}

Expand Down Expand Up @@ -573,7 +574,7 @@ Time64_T mktime64(struct TM *input_date) {
/* Correct the user's possibly out of bound input date */
copy_tm_to_TM64(&safe_date, input_date);

time += seconds_between_years(year, (Year)(safe_date.tm_year + 1900));
time += seconds_between_years_with_same_daycount(year, (Year)(safe_date.tm_year + 1900));
TIME64_TRACE1("mktime64 => %"PRId64" seconds\n", time);

return time;
Expand Down