diff --git a/web_src/js/components/RepoCodeFrequency.vue b/web_src/js/components/RepoCodeFrequency.vue index adce431264..1d40d6d417 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 2347c41ae4..f7b05831e0 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 502af533da..8759978e78 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 1848792c98..7c7eabd1a3 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) -export function startDaysBetween(startDate, endDate) { - // Ensure the start date is a Sunday - while (startDate.getDay() !== 0) { - startDate.setDate(startDate.getDate() + 1); - } +dayjs.extend(utc); - const start = dayjs(startDate); - const end = dayjs(endDate); - const startDays = []; +/** + * 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 (current.day() !== 0) { + current = current.add(1, 'day'); + } + + const startDays = []; 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(); }