From 44ad644df8569dd87c749f042c50e189a2c81f3e Mon Sep 17 00:00:00 2001 From: Sam Fisher Date: Fri, 3 May 2024 20:24:00 -0700 Subject: [PATCH 1/3] Have time.js use UTC-related getters/setters when working with `Date` --- web_src/js/utils/time.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/utils/time.js b/web_src/js/utils/time.js index 1848792c984c9..246ee4a2afc9a 100644 --- a/web_src/js/utils/time.js +++ b/web_src/js/utils/time.js @@ -4,8 +4,8 @@ import {getCurrentLocale} from '../utils.js'; // Returns an array of millisecond-timestamps of start-of-week days (Sundays) export function startDaysBetween(startDate, endDate) { // Ensure the start date is a Sunday - while (startDate.getDay() !== 0) { - startDate.setDate(startDate.getDate() + 1); + while (startDate.getUTCDay() !== 0) { + startDate.setUTCDate(startDate.getUTCDate() + 1); } const start = dayjs(startDate); From 4c6b1969023c1c68221ad8dc9bdb98fd99f0473d Mon Sep 17 00:00:00 2001 From: Kemal Zebari Date: Fri, 3 May 2024 22:39:42 -0700 Subject: [PATCH 2/3] Have `firstStartDateAfterDate()` use UTC-related methods --- web_src/js/utils/time.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/utils/time.js b/web_src/js/utils/time.js index 246ee4a2afc9a..016a82e1c5407 100644 --- a/web_src/js/utils/time.js +++ b/web_src/js/utils/time.js @@ -29,10 +29,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(); } From e455c216b2a83f9208fe41e84a98146be08503ce Mon Sep 17 00:00:00 2001 From: Kemal Zebari Date: Sat, 4 May 2024 18:53:23 -0700 Subject: [PATCH 3/3] Integrate dayjs utc plugin... again No more infinite loop! --- web_src/js/components/RepoCodeFrequency.vue | 2 +- web_src/js/components/RepoContributors.vue | 2 +- web_src/js/components/RepoRecentCommits.vue | 2 +- web_src/js/utils/time.js | 29 ++++++++++++--------- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/web_src/js/components/RepoCodeFrequency.vue b/web_src/js/components/RepoCodeFrequency.vue index adce431264513..1d40d6d417d54 100644 --- a/web_src/js/components/RepoCodeFrequency.vue +++ b/web_src/js/components/RepoCodeFrequency.vue @@ -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 { diff --git a/web_src/js/components/RepoContributors.vue b/web_src/js/components/RepoContributors.vue index 2347c41ae47ad..f7b05831e07b3 100644 --- a/web_src/js/components/RepoContributors.vue +++ b/web_src/js/components/RepoContributors.vue @@ -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; diff --git a/web_src/js/components/RepoRecentCommits.vue b/web_src/js/components/RepoRecentCommits.vue index 502af533da5da..8759978e788db 100644 --- a/web_src/js/components/RepoRecentCommits.vue +++ b/web_src/js/components/RepoRecentCommits.vue @@ -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 { diff --git a/web_src/js/utils/time.js b/web_src/js/utils/time.js index 016a82e1c5407..7c7eabd1a3624 100644 --- a/web_src/js/utils/time.js +++ b/web_src/js/utils/time.js @@ -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.getUTCDay() !== 0) { - startDate.setUTCDate(startDate.getUTCDate() + 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;