Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Calendar Matrix (date-fns, ES6) inspired by https://github.com/bclinkinbeard/calendar-matrix
import getYear from 'date-fns/get_year'
import getMonth from 'date-fns/get_month'
import addDays from 'date-fns/add_days'
import startOfWeek from 'date-fns/start_of_week'
const rows = range(6)
const cols = range(7)
/**
* Returns a two-dimensional array with calendar represented dates
*/
export default function ({ year, month, weekStartsOn } = {
year: getYear(new Date()),
month: getMonth(new Date()),
weekStartsOn: 0
}) {
const matrix = []
const date = new Date(year, month)
let curDate = startOfWeek(date, { weekStartsOn })
rows.forEach(row => {
const week = []
cols.forEach(col => {
week.push(curDate)
curDate = addDays(curDate, 1)
})
matrix.push(week)
})
return matrix
}
/**
* Returns an array range from 0 to n
*/
function range (n) {
return [...Array(n).keys()]
}
@boazblake
Copy link

boazblake commented Jul 30, 2020

there is a small bug in the getMountMatrix function. You are actually returning back January and not December. You should be setting the date to the previous month:
(also I believe you meant month instead of mount)

const date = new Date(parseInt(year), parseInt(mount) - 1);

@notiv-nt
Copy link

notiv-nt commented Jan 3, 2022

Easier way, @retyui take a look

import { eachDayOfInterval, endOfWeek, startOfWeek } from 'date-fns'; // 2.2k (gzipped: 989)

function createCalendar(year: number, month: number): Date[] {
  const start = startOfWeek(new Date(year, month, 1), { weekStartsOn: 1 /* Monday */ });
  const end = endOfWeek(new Date(year, month + 1, 1), { weekStartsOn: 1 /* Monday */ });
  return eachDayOfInterval({ start, end });
}

const calendar = createCalendar(2022, 0 /* January */);

console.log(calendar); // Array<Date> between '27 Dec 2021' and '6 Feb 2022'

https://codesandbox.io/s/amazing-keldysh-7r41u

@anishdcruz
Copy link

anishdcruz commented Jul 9, 2022

@notiv-nt Your code was perfect, but I noticed that for some months there were only five rows rather than six.

Here is the fix :)

import {
  addWeeks,
  eachDayOfInterval,
  endOfWeek,
  startOfMonth,
  startOfWeek,
} from 'date-fns'

export function createCalendar(today: Date): Date[] {
  const start = startOfWeek(startOfMonth(today), {
    weekStartsOn: 1 /* Monday */,
  })
  const end = endOfWeek(addWeeks(start, 5), {
    weekStartsOn: 1 /* Monday */,
  })
  return eachDayOfInterval({ start, end })
}

const calendar = createCalendar(new Date());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment