1import dayjs from 'dayjs';
2import utc from 'dayjs/plugin/utc.js';
3import {getCurrentLocale} from '../utils.js';
4
5dayjs.extend(utc);
6
7/**
8 * Returns an array of millisecond-timestamps of start-of-week days (Sundays)
9 *
10 * @param startConfig The start date. Can take any type that `Date` accepts.
11 * @param endConfig The end date. Can take any type that `Date` accepts.
12 */
13export function startDaysBetween(startDate, endDate) {
14 const start = dayjs.utc(startDate);
15 const end = dayjs.utc(endDate);
16
17 let current = start;
18
19 // Ensure the start date is a Sunday
20 while (current.day() !== 0) {
21 current = current.add(1, 'day');
22 }
23
24 const startDays = [];
25 while (current.isBefore(end)) {
26 startDays.push(current.valueOf());
27 current = current.add(1, 'week');
28 }
29
30 return startDays;
31}
32
33export function firstStartDateAfterDate(inputDate) {
34 if (!(inputDate instanceof Date)) {
35 throw new Error('Invalid date');
36 }
37 const dayOfWeek = inputDate.getUTCDay();
38 const daysUntilSunday = 7 - dayOfWeek;
39 const resultDate = new Date(inputDate);
40 resultDate.setUTCDate(resultDate.getUTCDate() + daysUntilSunday);
41 return resultDate.valueOf();
42}
43
44export function fillEmptyStartDaysWithZeroes(startDays, data) {
45 const result = {};
46
47 for (const startDay of startDays) {
48 result[startDay] = data[startDay] || {'week': startDay, 'additions': 0, 'deletions': 0, 'commits': 0};
49 }
50
51 return Object.values(result);
52}
53
54let dateFormat;
55
56// format a Date object to document's locale, but with 24h format from user's current locale because this
57// option is a personal preference of the user, not something that the document's locale should dictate.
58export function formatDatetime(date) {
59 if (!dateFormat) {
60 // TODO: replace `hour12` with `Intl.Locale.prototype.getHourCycles` once there is broad browser support
61 dateFormat = new Intl.DateTimeFormat(getCurrentLocale(), {
62 day: 'numeric',
63 month: 'short',
64 year: 'numeric',
65 hour: 'numeric',
66 hour12: !Number.isInteger(Number(new Intl.DateTimeFormat([], {hour: 'numeric'}).format())),
67 minute: '2-digit',
68 timeZoneName: 'short',
69 });
70 }
71 return dateFormat.format(date);
72}