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

Have time.js use UTC-related getters/setters #30857

Merged
merged 6 commits into from
May 6, 2024
Merged

Conversation

kemzeb
Copy link
Contributor

@kemzeb kemzeb commented May 4, 2024

Before this patch, we were using Date getter/setter methods that worked with local time to get a list of Sundays that are in the range of some start date and end date. The problem with this was that the Sundays are in Unix epoch time and when we changed the "startDate" argument that was passed to make sure it is on a Sunday, this change would be reflected when we convert it to Unix epoch time. More specifically, I observed that we may get different Unix epochs depending on your timezone when the returned list should rather be timezone-agnostic.

This led to issues in US timezones that caused the contributor, code frequency, and recent commit charts to not show any chart data. This fix resolves this by using getter/setter methods that work with UTC since it isn't dependent on timezones.

Fixes #30851.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label May 4, 2024
@pull-request-size pull-request-size bot added the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label May 4, 2024
@wxiaoguang
Copy link
Contributor

Thank you for the fix.

TBH I didn't quite get the point how the bug occurs, and why UTC fixes the bug .... if the problem could be clarified, maybe we could also add some tests

@kemzeb
Copy link
Contributor Author

kemzeb commented May 4, 2024

Yes, after looking at this for some time I observed that the output of startDaysBetween() was different when I switched from PDT to China Standard Time. This should not be the case because each element in the array should be in Unix epoch time, which isn't dependent on timezones.

I'm am not well versed in working with Date-related APIs yet, but I believed that these differing values were caused by the while loop trying to modify the start date to be on a Sunday. Depending on your timezone, startDate would be given a different Unix epoch time because it may have been changed in the loop. I thought by working with UTC time, the start date won't be changed depending on your timezone.

If you see this approach as an issue please let me know!

Edit: I changed my PR description to better explain the problem at hand.

@wxiaoguang
Copy link
Contributor

Take a quick look:

  1. There is another getDay call in firstStartDateAfterDate , is it right or not?
  2. There are tests in time.test.js, I think this case should be covered.

@kemzeb
Copy link
Contributor Author

kemzeb commented May 4, 2024

  1. There is another getDay call in firstStartDateAfterDate , is it right or not?

Sorry I wasn't specific enough about describing the problem. It is caused by both startDaysBetween() generating bad Unix epochs and the following function failing to map to the backend's own "start of the week" list that we pass to it:

export function fillEmptyStartDaysWithZeroes(startDays, data) {
const result = {};
for (const startDay of startDays) {
result[startDay] = data[startDay] || {'week': startDay, 'additions': 0, 'deletions': 0, 'commits': 0};
}
return Object.values(result);
}

This is what causes the chart data to not be displayed. Regarding your question, I don't think it would be an issue to use UTC-based methods here too. I'll make the changes.

  1. There are tests in time.test.js, I think this case should be covered.

I agree, I'll go ahead and add one or two there.

@kemzeb
Copy link
Contributor Author

kemzeb commented May 4, 2024

Recent changes has firstStartDateAfterDate() use UTC-related methods.

Having some trouble writing a test for startDaysBetween() since I want the test to make sure that its output remains the same when working with Date objects that have different local times. There doesn't seem to be a way to change the timezone that local time refers to but I'll keep looking

@pull-request-size pull-request-size bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels May 4, 2024
@kemzeb
Copy link
Contributor Author

kemzeb commented May 4, 2024

Decided to refactor startDaysBetween() to use dayjs's utc plugin. By default dayjs() would assume we are working with local time when making calls like the add() call does (read about it here). This change no longer has us worry about working with local time here.

I manually tested with PDT and China Standard Time on all 3 Activity pages and it appears to work fine.

I wondered if the dayjs.extend() call would be a problem (i.e. if it would be used elsewhere in the future), but dayjs handles this case. See here.

I am still pondering how to test this. As I said this test should ensure that the output of this function remains the same when dealing with different timezones, but I haven't seen a way to temporarily change the timezone when working with Date or dayjs objects.

dayjs does have a timezone plugin but it is just meant for parsing and displaying timezones; it won't affect dayjs() (i.e. it will still use the local time).

@kemzeb kemzeb changed the title Have time.js use UTC-related getters/setters when working with Date Have time.js use UTC-related getters/setters May 4, 2024
@pull-request-size pull-request-size bot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels May 5, 2024
@kemzeb
Copy link
Contributor Author

kemzeb commented May 5, 2024

So... after integrating dayjs's utc plugin it worked perfectly fine in my dev environment but when running the frontend tests it freezes when it reaches time.test.js (deadlock?). I decided to revert my changes to keep using the Date object for now as I not sure what caused the freeze.

Edit: Ohh I see the problem. The while was running in an infinite loop (I forgot that dayjs objects are immutable). When I was manually testing I may have been using an older cached version of the page. Well go back to using the dayjs approach.

No more infinite loop!
@pull-request-size pull-request-size bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels May 5, 2024
@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels May 5, 2024
@wxiaoguang wxiaoguang added type/bug backport/v1.22 This PR should be backported to Gitea 1.22 labels May 5, 2024
@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels May 5, 2024
@lunny lunny added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label May 5, 2024
@lunny lunny merged commit 22c7b3a into go-gitea:main May 6, 2024
26 checks passed
@GiteaBot GiteaBot added this to the 1.23.0 milestone May 6, 2024
GiteaBot pushed a commit to GiteaBot/gitea that referenced this pull request May 6, 2024
Before this patch, we were using `Date` getter/setter methods that
worked with local time to get a list of Sundays that are in the range of
some start date and end date. The problem with this was that the Sundays
are in Unix epoch time and when we changed the "startDate" argument that
was passed to make sure it is on a Sunday, this change would be
reflected when we convert it to Unix epoch time. More specifically, I
observed that we may get different Unix epochs depending on your
timezone when the returned list should rather be timezone-agnostic.

This led to issues in US timezones that caused the contributor, code
frequency, and recent commit charts to not show any chart data. This fix
resolves this by using getter/setter methods that work with UTC since it
isn't dependent on timezones.

Fixes go-gitea#30851.

---------

Co-authored-by: Sam Fisher <fisher@3echelon.local>
@GiteaBot GiteaBot added backport/done All backports for this PR have been created and removed reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. labels May 6, 2024
wxiaoguang pushed a commit that referenced this pull request May 6, 2024
Backport #30857 by kemzeb

Co-authored-by: Kemal Zebari <60799661+kemzeb@users.noreply.github.com>
Co-authored-by: Sam Fisher <fisher@3echelon.local>
@kemzeb
Copy link
Contributor Author

kemzeb commented May 6, 2024

Thanks! Looking at the main's commit history, it looks like embarrassingly forgot to set my git username and email on another machine I was using 😂.

@kemzeb kemzeb deleted the fix-frontend branch May 6, 2024 02:09
zjjhot added a commit to zjjhot/gitea that referenced this pull request May 6, 2024
* giteaofficial/main:
  Have time.js use UTC-related getters/setters (go-gitea#30857)
  Do not show monaco JS errors (go-gitea#30862)
  Fix issue/PR title edit (go-gitea#30858)
  Add result check in TestAPIEditUser (go-gitea#29674)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/done All backports for this PR have been created backport/v1.22 This PR should be backported to Gitea 1.22 lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. modifies/js size/M Denotes a PR that changes 30-99 lines, ignoring generated files. type/bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Activity pages (besides Pulse) seem to no longer work
4 participants