UNPKG

react-calendar

Version:

Ultimate calendar for your React app.

341 lines (340 loc) 11.8 kB
import { getYear, getMonth as getMonthIndex, getCenturyStart, getPreviousCenturyStart, getNextCenturyStart, getCenturyEnd, getPreviousCenturyEnd, getCenturyRange, getDecadeStart, getPreviousDecadeStart, getNextDecadeStart, getDecadeEnd, getPreviousDecadeEnd, getDecadeRange, getYearStart, getPreviousYearStart, getNextYearStart, getYearEnd, getPreviousYearEnd, getYearRange, getMonthStart, getPreviousMonthStart, getNextMonthStart, getMonthEnd, getPreviousMonthEnd, getMonthRange, getDayStart, getDayEnd, getDayRange, } from '@wojtekmaj/date-utils'; import { CALENDAR_TYPES, WEEKDAYS } from './const.js'; import { formatYear as defaultFormatYear } from './dateFormatter.js'; var SUNDAY = WEEKDAYS[0]; var FRIDAY = WEEKDAYS[5]; var SATURDAY = WEEKDAYS[6]; /* Simple getters - getting a property of a given point in time */ /** * Gets day of the week of a given date. * @param {Date} date Date. * @param {CalendarType} [calendarType="iso8601"] Calendar type. * @returns {number} Day of the week. */ export function getDayOfWeek(date, calendarType) { if (calendarType === void 0) { calendarType = CALENDAR_TYPES.ISO_8601; } var weekday = date.getDay(); switch (calendarType) { case CALENDAR_TYPES.ISO_8601: // Shifts days of the week so that Monday is 0, Sunday is 6 return (weekday + 6) % 7; case CALENDAR_TYPES.ISLAMIC: return (weekday + 1) % 7; case CALENDAR_TYPES.HEBREW: case CALENDAR_TYPES.GREGORY: return weekday; default: throw new Error('Unsupported calendar type.'); } } /** * Century */ /** * Gets the year of the beginning of a century of a given date. * @param {Date} date Date. * @returns {number} Year of the beginning of a century. */ export function getBeginOfCenturyYear(date) { var beginOfCentury = getCenturyStart(date); return getYear(beginOfCentury); } /** * Decade */ /** * Gets the year of the beginning of a decade of a given date. * @param {Date} date Date. * @returns {number} Year of the beginning of a decade. */ export function getBeginOfDecadeYear(date) { var beginOfDecade = getDecadeStart(date); return getYear(beginOfDecade); } /** * Week */ /** * Returns the beginning of a given week. * * @param {Date} date Date. * @param {CalendarType} [calendarType="iso8601"] Calendar type. * @returns {Date} Beginning of a given week. */ export function getBeginOfWeek(date, calendarType) { if (calendarType === void 0) { calendarType = CALENDAR_TYPES.ISO_8601; } var year = getYear(date); var monthIndex = getMonthIndex(date); var day = date.getDate() - getDayOfWeek(date, calendarType); return new Date(year, monthIndex, day); } /** * Gets week number according to ISO 8601 or US standard. * In ISO 8601, Arabic and Hebrew week 1 is the one with January 4. * In US calendar week 1 is the one with January 1. * * @param {Date} date Date. * @param {CalendarType} [calendarType="iso8601"] Calendar type. * @returns {number} Week number. */ export function getWeekNumber(date, calendarType) { if (calendarType === void 0) { calendarType = CALENDAR_TYPES.ISO_8601; } var calendarTypeForWeekNumber = calendarType === CALENDAR_TYPES.GREGORY ? CALENDAR_TYPES.GREGORY : CALENDAR_TYPES.ISO_8601; var beginOfWeek = getBeginOfWeek(date, calendarType); var year = getYear(date) + 1; var dayInWeekOne; var beginOfFirstWeek; // Look for the first week one that does not come after a given date do { dayInWeekOne = new Date(year, 0, calendarTypeForWeekNumber === CALENDAR_TYPES.ISO_8601 ? 4 : 1); beginOfFirstWeek = getBeginOfWeek(dayInWeekOne, calendarType); year -= 1; } while (date < beginOfFirstWeek); return Math.round((beginOfWeek.getTime() - beginOfFirstWeek.getTime()) / (8.64e7 * 7)) + 1; } /** * Others */ /** * Returns the beginning of a given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date} Beginning of a given range. */ export function getBegin(rangeType, date) { switch (rangeType) { case 'century': return getCenturyStart(date); case 'decade': return getDecadeStart(date); case 'year': return getYearStart(date); case 'month': return getMonthStart(date); case 'day': return getDayStart(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Returns the beginning of a previous given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date} Beginning of a previous given range. */ export function getBeginPrevious(rangeType, date) { switch (rangeType) { case 'century': return getPreviousCenturyStart(date); case 'decade': return getPreviousDecadeStart(date); case 'year': return getPreviousYearStart(date); case 'month': return getPreviousMonthStart(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Returns the beginning of a next given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date} Beginning of a next given range. */ export function getBeginNext(rangeType, date) { switch (rangeType) { case 'century': return getNextCenturyStart(date); case 'decade': return getNextDecadeStart(date); case 'year': return getNextYearStart(date); case 'month': return getNextMonthStart(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } export function getBeginPrevious2(rangeType, date) { switch (rangeType) { case 'decade': return getPreviousDecadeStart(date, -100); case 'year': return getPreviousYearStart(date, -10); case 'month': return getPreviousMonthStart(date, -12); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } export function getBeginNext2(rangeType, date) { switch (rangeType) { case 'decade': return getNextDecadeStart(date, 100); case 'year': return getNextYearStart(date, 10); case 'month': return getNextMonthStart(date, 12); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Returns the end of a given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date} End of a given range. */ export function getEnd(rangeType, date) { switch (rangeType) { case 'century': return getCenturyEnd(date); case 'decade': return getDecadeEnd(date); case 'year': return getYearEnd(date); case 'month': return getMonthEnd(date); case 'day': return getDayEnd(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Returns the end of a previous given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date} End of a previous given range. */ export function getEndPrevious(rangeType, date) { switch (rangeType) { case 'century': return getPreviousCenturyEnd(date); case 'decade': return getPreviousDecadeEnd(date); case 'year': return getPreviousYearEnd(date); case 'month': return getPreviousMonthEnd(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } export function getEndPrevious2(rangeType, date) { switch (rangeType) { case 'decade': return getPreviousDecadeEnd(date, -100); case 'year': return getPreviousYearEnd(date, -10); case 'month': return getPreviousMonthEnd(date, -12); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Returns an array with the beginning and the end of a given range. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date Date. * @returns {Date[]} Beginning and end of a given range. */ export function getRange(rangeType, date) { switch (rangeType) { case 'century': return getCenturyRange(date); case 'decade': return getDecadeRange(date); case 'year': return getYearRange(date); case 'month': return getMonthRange(date); case 'day': return getDayRange(date); default: throw new Error("Invalid rangeType: ".concat(rangeType)); } } /** * Creates a range out of two values, ensuring they are in order and covering entire period ranges. * * @param {RangeType} rangeType Range type (e.g. 'day') * @param {Date} date1 First date. * @param {Date} date2 Second date. * @returns {Date[]} Beginning and end of a given range. */ export function getValueRange(rangeType, date1, date2) { var rawNextValue = [date1, date2].sort(function (a, b) { return a.getTime() - b.getTime(); }); return [getBegin(rangeType, rawNextValue[0]), getEnd(rangeType, rawNextValue[1])]; } function toYearLabel(locale, formatYear, dates) { return dates.map(function (date) { return (formatYear || defaultFormatYear)(locale, date); }).join(' – '); } /** * @callback FormatYear * @param {string} locale Locale. * @param {Date} date Date. * @returns {string} Formatted year. */ /** * Returns a string labelling a century of a given date. * For example, for 2017 it will return 2001-2100. * * @param {string} locale Locale. * @param {FormatYear} formatYear Function to format a year. * @param {Date|string|number} date Date or a year as a string or as a number. * @returns {string} String labelling a century of a given date. */ export function getCenturyLabel(locale, formatYear, date) { return toYearLabel(locale, formatYear, getCenturyRange(date)); } /** * Returns a string labelling a decade of a given date. * For example, for 2017 it will return 2011-2020. * * @param {string} locale Locale. * @param {FormatYear} formatYear Function to format a year. * @param {Date|string|number} date Date or a year as a string or as a number. * @returns {string} String labelling a decade of a given date. */ export function getDecadeLabel(locale, formatYear, date) { return toYearLabel(locale, formatYear, getDecadeRange(date)); } /** * Returns a boolean determining whether a given date is the current day of the week. * * @param {Date} date Date. * @returns {boolean} Whether a given date is the current day of the week. */ export function isCurrentDayOfWeek(date) { return date.getDay() === new Date().getDay(); } /** * Returns a boolean determining whether a given date is a weekend day. * * @param {Date} date Date. * @param {CalendarType} [calendarType="iso8601"] Calendar type. * @returns {boolean} Whether a given date is a weekend day. */ export function isWeekend(date, calendarType) { if (calendarType === void 0) { calendarType = CALENDAR_TYPES.ISO_8601; } var weekday = date.getDay(); switch (calendarType) { case CALENDAR_TYPES.ISLAMIC: case CALENDAR_TYPES.HEBREW: return weekday === FRIDAY || weekday === SATURDAY; case CALENDAR_TYPES.ISO_8601: case CALENDAR_TYPES.GREGORY: return weekday === SATURDAY || weekday === SUNDAY; default: throw new Error('Unsupported calendar type.'); } }