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 bug in formatting timestamps with gmtime_r #293

Merged
merged 1 commit into from
Sep 27, 2023

Conversation

jmaksymowicz
Copy link
Contributor

@jmaksymowicz jmaksymowicz commented Sep 19, 2023

Description

Timestamps that were far into the future (beyond about year 14000) were parsed incorrectly because the previous algorithm assumed too many leap years.

Related to phoenix-rtos/phoenix-rtos-project#801 - in one example time on RTC was set correctly to maximum timestamp minus the given number of seconds, but displayed incorrectly due to this bug.

Motivation and Context

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

How Has This Been Tested?

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
@nalajcie
Copy link
Member

please format the commit message title better:

  • use max 76 chars
  • use imperative mood
  • prefix with module name

For example: time: fix counting leap years in gmtime_r
(for more examples - see git history :))

You should also append JIRA ticket ID to the commit message trailer

@github-actions
Copy link

github-actions bot commented Sep 21, 2023

Unit Test Results

5 721 tests   5 076 ✔️  23m 43s ⏱️
   290 suites     645 💤
       1 files           0

Results for commit c142ebf.

♻️ This comment has been updated with latest results.

Copy link
Member

@agkaminski agkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is leapcount() still needed? It shoudn't be, as it's buggy, so it should be removed

time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
time/time.c Outdated Show resolved Hide resolved
@agkaminski agkaminski changed the title Fixed bug in formatting timestamps with gmtime_r Fix bug in formatting timestamps with gmtime_r Sep 22, 2023
time/time.c Outdated Show resolved Hide resolved
agkaminski
agkaminski previously approved these changes Sep 22, 2023
Copy link
Member

@agkaminski agkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kemonats
Copy link
Contributor

kemonats commented Sep 24, 2023

Some issues:

  1. time_t is of type unsigned long long, why check seconds, minutes, hours < 0, the compiler will skip these if statements.
  2. if gmtime_r() can return NULL then this should be checked in the ctime_r() function:
char *ctime_r(const time_t *timep, char *buf)
{
	struct tm t, *tp;

	tp = localtime_r(timep, &t);

	return (tp == NULL) ? NULL : asctime_r(&t, buf);
}
  1. suggestion:
    for 32-bit arm platform one 64-bit divide ( function __aeabi_uldivmod ) instead of six ( for this version of the compiler )
	int seconds, minutes, hours;
	int days, month, year, isYearLeap;

	days = *timep / (24 * 60 * 60);
	seconds = *timep - (time_t)days * (24 * 60 * 60);
#if 0 /* insert it if `time_t` is signed */
	if (seconds < 0) {
		days--;
		seconds += (24 * 60 * 60);
	}
#endif

	hours = seconds / (60 * 60);
	seconds = seconds % (60 * 60);

	minutes = seconds / 60;
	seconds = seconds % 60;

	res->tm_sec = seconds;
	res->tm_min = minutes;
	res->tm_hour = hours;

/* the rest of the code */

@agkaminski
Copy link
Member

@kemonats

  1. We decided to slowly prepare the code for signed time_t. As you've noticed, these checks are optimized-out by the compiler, so it doesn't hurt anything (apart from perhaps some confusion and desire to remove them for now),
  2. I agree, this needs to be fixed,
  3. This way you sacrifice resolution of time_t - yes, it's still about 4000 years we're able to represent. It's your call @jmaksymowicz, entry check need to be changed in that case.

@agkaminski agkaminski self-requested a review September 25, 2023 07:30
@jmaksymowicz
Copy link
Contributor Author

  1. As @agkaminski said, we're preparing to use a signed type for time_t, so while correcting the algorithm I also made it ready for negative numbers.
  2. I will fix it
  3. It's a good point to change it, fewer 64-bit divisions is better. I don't see how it sacrifices resolution, the resulting variable days is same as before and the variable seconds will not exceed +/-86400.

@agkaminski
Copy link
Member

  1. I misunderstood the code, there's no reduction in resolution. So I see no cons to kemonats's approach

time/time.c Outdated Show resolved Hide resolved
@jmaksymowicz jmaksymowicz force-pushed the time_formatting_fix branch 2 times, most recently from c0ffa7e to 8eafb34 Compare September 25, 2023 13:11
time: limit acceptable timestamp range in gmtime_r
time: improve mktime and gmtime_r to work with negative timestamps

JIRA: RTOS-609
Copy link
Member

@agkaminski agkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@agkaminski agkaminski merged commit 0ff2388 into master Sep 27, 2023
30 checks passed
@agkaminski agkaminski deleted the time_formatting_fix branch September 27, 2023 14:08
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.

4 participants