简易日历生成器

/**
 * @description: 生成日历表
 * @param {number} year 年份
 * @param {number} month 月份
 * @param {number} start 日历表起始星期 0-6
 * @return {object} cHead 日历表头部 cBody 日历表主体
 */
function execCalendar(year, month, start = 0) {
  // 根据日历表的单行起始星期推出结束星期 如 日一二三四五六 或 一二三四五六日
  let weeks = [],
    week = [],
    head = [];
  let count = start;
  const weekend = (start + 6) % 7;
  // 获取本月第一天星期
  const firstday = new Date(year, month, 1).getDay();
  // 获取本月最后一天日期
  const last = new Date(year, month + 1, 0).getDate();

  // 计算起始位置
  let n = 1 + start - firstday;
  if (n > 1) n = n - 7;

  while (1) {
    week.push(new Date(year, month, n));
    if (count % 7 === weekend) {
      weeks.push(week);
      week = [];
      if (n >= last) break;
    }
    n++, count++;
  }
  count = start;
  while (head.length < 7) {
    head.push(count % 7);
    count++;
  }

  return {
    cHead: head,
    cBody: weeks,
  };
}

// execCalendar(2023, 7, 0)
{
  cHead: [0, 1, 2, 3, 4, 5, 6],
  cBody: [
    [
      "2023-07-29T16:00:00.000Z",
      "2023-07-30T16:00:00.000Z",
      "2023-07-31T16:00:00.000Z",
      "2023-08-01T16:00:00.000Z",
      "2023-08-02T16:00:00.000Z",
      "2023-08-03T16:00:00.000Z",
      "2023-08-04T16:00:00.000Z",
    ],
    [
      "2023-08-05T16:00:00.000Z",
      "2023-08-06T16:00:00.000Z",
      "2023-08-07T16:00:00.000Z",
      "2023-08-08T16:00:00.000Z",
      "2023-08-09T16:00:00.000Z",
      "2023-08-10T16:00:00.000Z",
      "2023-08-11T16:00:00.000Z",
    ],
    [
      "2023-08-12T16:00:00.000Z",
      "2023-08-13T16:00:00.000Z",
      "2023-08-14T16:00:00.000Z",
      "2023-08-15T16:00:00.000Z",
      "2023-08-16T16:00:00.000Z",
      "2023-08-17T16:00:00.000Z",
      "2023-08-18T16:00:00.000Z",
    ],
    [
      "2023-08-19T16:00:00.000Z",
      "2023-08-20T16:00:00.000Z",
      "2023-08-21T16:00:00.000Z",
      "2023-08-22T16:00:00.000Z",
      "2023-08-23T16:00:00.000Z",
      "2023-08-24T16:00:00.000Z",
      "2023-08-25T16:00:00.000Z",
    ],
    [
      "2023-08-26T16:00:00.000Z",
      "2023-08-27T16:00:00.000Z",
      "2023-08-28T16:00:00.000Z",
      "2023-08-29T16:00:00.000Z",
      "2023-08-30T16:00:00.000Z",
      "2023-08-31T16:00:00.000Z",
      "2023-09-01T16:00:00.000Z",
    ],
  ],
};