生成の流れ
- 対象月の日数を調べる
- カレンダー上で、1日の前に何日(何マス)あるか
- カレンダー上で、最終日の後ろに何日(何マス)あるか
- カレンダーに表示される日数を調べる
- 日数分の配列を生成
- chunkする
- 最終的に
[Array(7), Array(7), Array(7), Array(7), Array(7)]
のような配列になる
サンプル
週の開始を変更したい場合
import chunk from 'lodash/fp/chunk';
import compose from 'lodash/fp/compose';
import map from 'lodash/fp/map';
import range from 'lodash/fp/range';
import * as moment from 'moment';
const DAYS_PER_WEEK = 7;
export function createCalendar(
m = moment(),
startDayOfWeek = 0) {
const startOfMonth: moment.Moment = m.clone().startOf('month');
const daysInMonth: number = m.clone().endOf('month').date();
const daysBefore: number = getDaysBefore(startOfMonth, startDayOfWeek);
const daysAfter: number = getDaysAfter(daysBefore, daysInMonth);
const diffs: number[] = getDiffs(daysBefore, daysInMonth, daysAfter);
return compose(
chunk(DAYS_PER_WEEK),
map((diff) => startOfMonth.clone().add(diff, 'd'))
)(diffs);
}
function getDaysBefore(startOfMonth: moment.Moment, startDayOfWeek: number): number {
const dayOfWeek = startOfMonth.day();
return (dayOfWeek + DAYS_PER_WEEK - startDayOfWeek) % DAYS_PER_WEEK;
}
function getDaysAfter(daysBefore: number, daysInMonth: number): number {
return DAYS_PER_WEEK - (daysBefore + daysInMonth) % DAYS_PER_WEEK;
}
function getDiffs(daysBefore, daysInMonth, daysAfter): number[] {
return range((daysBefore * -1), daysInMonth + daysAfter)
}