]> source.dussan.org Git - gitea.git/commitdiff
Have time.js use UTC-related getters/setters (#30857)
authorKemal Zebari <60799661+kemzeb@users.noreply.github.com>
Mon, 6 May 2024 01:36:53 +0000 (18:36 -0700)
committerGitHub <noreply@github.com>
Mon, 6 May 2024 01:36:53 +0000 (09:36 +0800)
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.

---------

Co-authored-by: Sam Fisher <fisher@3echelon.local>
web_src/js/components/RepoCodeFrequency.vue
web_src/js/components/RepoContributors.vue
web_src/js/components/RepoRecentCommits.vue
web_src/js/utils/time.js

index adce431264513dcf88f2dc587cfc6e642f5097b0..1d40d6d417d54eb4e0782bd840fdecd8fa1c346f 100644 (file)
@@ -67,7 +67,7 @@ export default {
           const weekValues = Object.values(this.data);
           const start = weekValues[0].week;
           const end = firstStartDateAfterDate(new Date());
-          const startDays = startDaysBetween(new Date(start), new Date(end));
+          const startDays = startDaysBetween(start, end);
           this.data = fillEmptyStartDaysWithZeroes(startDays, this.data);
           this.errorText = '';
         } else {
index 2347c41ae47add3e76857b7520497847053e7474..f7b05831e07b3c5f3e5ddc6737da3294e347d7a6 100644 (file)
@@ -114,7 +114,7 @@ export default {
           const weekValues = Object.values(total.weeks);
           this.xAxisStart = weekValues[0].week;
           this.xAxisEnd = firstStartDateAfterDate(new Date());
-          const startDays = startDaysBetween(new Date(this.xAxisStart), new Date(this.xAxisEnd));
+          const startDays = startDaysBetween(this.xAxisStart, this.xAxisEnd);
           total.weeks = fillEmptyStartDaysWithZeroes(startDays, total.weeks);
           this.xAxisMin = this.xAxisStart;
           this.xAxisMax = this.xAxisEnd;
index 502af533da5da3c7a28b99506cc0404262eaaa39..8759978e788db558b3622c7f059936cd576e73f2 100644 (file)
@@ -62,7 +62,7 @@ export default {
           const data = await response.json();
           const start = Object.values(data)[0].week;
           const end = firstStartDateAfterDate(new Date());
-          const startDays = startDaysBetween(new Date(start), new Date(end));
+          const startDays = startDaysBetween(start, end);
           this.data = fillEmptyStartDaysWithZeroes(startDays, data).slice(-52);
           this.errorText = '';
         } else {
index 1848792c984c9dd904d905f240a1a109e5cbd4f3..7c7eabd1a36246b1ec5c4946032afacf9b264b0a 100644 (file)
@@ -1,25 +1,30 @@
 import dayjs from 'dayjs';
+import utc from 'dayjs/plugin/utc.js';
 import {getCurrentLocale} from '../utils.js';
 
-// Returns an array of millisecond-timestamps of start-of-week days (Sundays)
+dayjs.extend(utc);
+
+/**
+ * Returns an array of millisecond-timestamps of start-of-week days (Sundays)
+ *
+ * @param startConfig The start date. Can take any type that `Date` accepts.
+ * @param endConfig The end date. Can take any type that `Date` accepts.
+ */
 export function startDaysBetween(startDate, endDate) {
+  const start = dayjs.utc(startDate);
+  const end = dayjs.utc(endDate);
+
+  let current = start;
+
   // Ensure the start date is a Sunday
-  while (startDate.getDay() !== 0) {
-    startDate.setDate(startDate.getDate() + 1);
+  while (current.day() !== 0) {
+    current = current.add(1, 'day');
   }
 
-  const start = dayjs(startDate);
-  const end = dayjs(endDate);
   const startDays = [];
-
-  let current = start;
   while (current.isBefore(end)) {
     startDays.push(current.valueOf());
-    // we are adding 7 * 24 hours instead of 1 week because we don't want
-    // date library to use local time zone to calculate 1 week from now.
-    // local time zone is problematic because of daylight saving time (dst)
-    // used on some countries
-    current = current.add(7 * 24, 'hour');
+    current = current.add(1, 'week');
   }
 
   return startDays;
@@ -29,10 +34,10 @@ export function firstStartDateAfterDate(inputDate) {
   if (!(inputDate instanceof Date)) {
     throw new Error('Invalid date');
   }
-  const dayOfWeek = inputDate.getDay();
+  const dayOfWeek = inputDate.getUTCDay();
   const daysUntilSunday = 7 - dayOfWeek;
   const resultDate = new Date(inputDate.getTime());
-  resultDate.setDate(resultDate.getDate() + daysUntilSunday);
+  resultDate.setUTCDate(resultDate.getUTCDate() + daysUntilSunday);
   return resultDate.valueOf();
 }