UNPKG

retail-calendar

Version:
202 lines (201 loc) 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var types_1 = require("./types"); var calendar_month_1 = require("./calendar_month"); var calendar_week_1 = require("./calendar_week"); var last_day_before_eom_1 = require("./last_day_before_eom"); var last_day_nearest_eom_1 = require("./last_day_nearest_eom"); var first_bow_of_first_month_1 = require("./first_bow_of_first_month"); var last_day_before_eom_except_leap_year_1 = require("./last_day_before_eom_except_leap_year"); var date_utils_1 = require("./date_utils"); var memoization_1 = require("./utils/memoization"); var penultimate_day_of_week_nearest_eom_1 = require("./penultimate_day_of_week_nearest_eom"); var custom_leap_year_1 = require("./custom_leap_year"); var buildRetailCalendarFactory = memoization_1.memoize(function (retailCalendarOptions, year) { return new exports.RetailCalendarFactory(retailCalendarOptions, year); }, function (retailCalendarOptions, year) { return memoization_1.createMemoizationKeyFromCalendarOptionsAndYear(retailCalendarOptions, year); }); exports.RetailCalendarFactory = /** @class */ (function () { function Calendar(calendarOptions, year) { var _a; this.year = year; this.options = calendarOptions; this.calendarYear = this.getAdjustedGregorianYear(year); this.addLeapWeekToMonth = (_a = this.options.addLeapWeekToMonth) !== null && _a !== void 0 ? _a : -1; this.numberOfWeeks = this.calculateNumberOfWeeks(); this.lastDayOfYear = this.calculateLastDayOfYear(this.calendarYear, this.year); this.firstDayOfYear = date_utils_1.startOfDay(date_utils_1.addDaysToDate(date_utils_1.addWeeksToDate(this.lastDayOfYear, -this.numberOfWeeks), 1)); this.weeks = this.generateWeeks(); this.months = this.generateMonths(); this.days = this.generateDays(); } Calendar.getRetailCalendar = function (retailCalendarOptions, year) { return buildRetailCalendarFactory(retailCalendarOptions, year); }; Calendar.prototype.generateMonths = function () { var months = []; var beginningIndex = this.getBeginningOfMonthIndex(); var index = beginningIndex; for (var _i = 0, _a = this.getWeekDistribution(); _i < _a.length; _i++) { var numberOfWeeks = _a[_i]; var quarterOfYear = Math.floor((index - beginningIndex) / 3) + 1; var weeksOfMonth = this.weeks.filter(function (week) { return week.monthOfYear === index; }); var monthStart = new Date(weeksOfMonth[0].gregorianStartDate); var monthEnd = new Date(weeksOfMonth[weeksOfMonth.length - 1].gregorianEndDate); months.push(new calendar_month_1.CalendarMonth(index, quarterOfYear, numberOfWeeks, weeksOfMonth, monthStart, monthEnd)); index += 1; } return months; }; Calendar.prototype.generateWeeks = function () { var weeks = []; for (var index = 0; index < this.numberOfWeeks; index++) { var weekIndex = index; var _a = this.getMonthAndWeekOfMonthOfWeek(weekIndex), monthOfYear = _a[0], weekOfMonth = _a[1], weekOfQuarter = _a[2], quarterOfYear = _a[3]; var start = date_utils_1.addWeeksToDate(this.firstDayOfYear, index); var end = date_utils_1.endOfDay(date_utils_1.addDaysToDate(date_utils_1.addWeeksToDate(start, 1), -1)); weeks.push(new calendar_week_1.CalendarWeek(weekIndex, weekOfMonth, weekOfQuarter, monthOfYear, quarterOfYear, start, end)); } return weeks; }; Calendar.prototype.generateDays = function () { var _this = this; var days = []; var DAYS_IN_WEEK = 7; var dayOfYear = 1; this.weeks.forEach(function (week) { for (var dayIndex = 1; dayIndex < DAYS_IN_WEEK + 1; dayIndex++) { var gregorianStartDate = date_utils_1.addDaysToDate(week.gregorianStartDate, dayIndex - 1); var gregorianEndDate = date_utils_1.endOfDay(gregorianStartDate); var gregorianMonthOfYear = gregorianStartDate.getMonth() + 1; // JS Date is 0 indexed var gregorianDayOfYear = date_utils_1.getDayOfYear(gregorianStartDate); var gregorianDayOfMonth = gregorianStartDate.getDate(); var isLeapWeek = _this.isLeapWeek(week.weekOfYear); days.push({ dayOfYear: dayOfYear, dayOfWeek: dayIndex, dayOfMonth: isLeapWeek ? -1 : week.weekOfMonth * 7 + dayIndex, weekOfYear: week.weekOfYear, monthOfYear: isLeapWeek ? -1 : week.monthOfYear, gregorianStartDate: gregorianStartDate, gregorianEndDate: gregorianEndDate, gregorianMonthOfYear: gregorianMonthOfYear, gregorianDayOfYear: gregorianDayOfYear, gregorianDayOfMonth: gregorianDayOfMonth, }); dayOfYear += 1; } }); return days; }; Calendar.prototype.isLeapWeek = function (weekIndex) { if (weekIndex !== 52) { return false; } // If addLeapWeekToMonth is greater than zero, then that month has one additional week. // As a result, the 52nd week is not a leap week. return this.addLeapWeekToMonth === -1; }; Calendar.prototype.getMonthAndWeekOfMonthOfWeek = function (weekIndex) { var weekDistribution = this.getWeekDistribution(); var monthOffset = this.getBeginningOfMonthIndex(); var weekCount = 0; var monthOfYear = 0; var weekInQuarter = 0; var quarterOfYear = 0; for (var monthIndex = 0; monthIndex < 12; monthIndex++) { var weeksInMonth = weekDistribution[monthIndex]; monthOfYear = monthIndex + monthOffset; if (monthIndex % 3 === 0) { weekInQuarter = 0; quarterOfYear = Math.floor(monthIndex / 3) + 1; } for (var weekInMonth = 0; weekInMonth < weeksInMonth; weekInMonth++) { if (weekIndex === weekCount) { return [monthOfYear, weekInMonth, weekInQuarter, quarterOfYear]; } weekCount++; weekInQuarter++; } } return [-1, -1, -1, -1]; }; Calendar.prototype.getBeginningOfMonthIndex = function () { var optionsIndex = this.options.beginningMonthIndex; if (optionsIndex !== undefined && optionsIndex !== null) { return optionsIndex; } else { return 1; } }; Calendar.prototype.getWeekDistribution = function () { var weekDistribution; switch (this.options.weekGrouping) { case types_1.WeekGrouping.Group445: weekDistribution = [4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5]; break; case types_1.WeekGrouping.Group454: weekDistribution = [4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4]; break; case types_1.WeekGrouping.Group544: weekDistribution = [5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4]; break; } if (this.options.addLeapWeekToMonth !== undefined && this.options.addLeapWeekToMonth >= 0 && this.numberOfWeeks === 53) weekDistribution[this.options.addLeapWeekToMonth]++; return weekDistribution; }; Calendar.prototype.calculateLastDayOfYear = function (year, retailCalendarYear) { var firstDayOfLastMonthOfYear = date_utils_1.newSafeDate(); firstDayOfLastMonthOfYear.setFullYear(year); firstDayOfLastMonthOfYear.setMonth(this.options.lastMonthOfYear, 1); var lastDayOfYear = date_utils_1.endOfMonth(firstDayOfLastMonthOfYear); var lastIsoWeekDay = this.options.lastDayOfWeek; var weekCalculation = this.getWeekCalculationStrategy(this.options.weekCalculation); return weekCalculation.getLastDayForGregorianLastDay(lastDayOfYear, lastIsoWeekDay, retailCalendarYear); }; Calendar.prototype.calculateNumberOfWeeks = function () { // Make sure we get whole day difference // by measuring from the end of current year to start of last year var lastDayOfYear = date_utils_1.endOfDay(this.calculateLastDayOfYear(this.calendarYear, this.year)); var lastDayOfLastYear = date_utils_1.startOfDay(this.calculateLastDayOfYear(this.calendarYear - 1, this.year - 1)); var numWeeks = date_utils_1.getWeekDifference(lastDayOfYear, lastDayOfLastYear); return numWeeks; }; Calendar.prototype.getWeekCalculationStrategy = function (weekCalculation) { switch (weekCalculation) { case types_1.WeekCalculation.LastDayBeforeEOM: return new last_day_before_eom_1.LastDayBeforeEOMStrategy(); case types_1.WeekCalculation.LastDayBeforeEomExceptLeapYear: return new last_day_before_eom_except_leap_year_1.LastDayBeforeEOMExceptLeapYearStrategy(); case types_1.WeekCalculation.LastDayNearestEOM: return new last_day_nearest_eom_1.LastDayNearestEOMStrategy(); case types_1.WeekCalculation.FirstBOWOfFirstMonth: return new first_bow_of_first_month_1.FirstBOWOfFirstMonth(); case types_1.WeekCalculation.PenultimateDayOfWeekNearestEOM: return new penultimate_day_of_week_nearest_eom_1.PenultimateDayOfWeekNearestEOMStrategy(); case types_1.WeekCalculation.CustomLeapYear: { var _a = this.options, leapYear = _a.leapYear, leapYearEndDate = _a.leapYearEndDate, leapYearFrequency = _a.leapYearFrequency; if (leapYear === undefined || leapYearEndDate === undefined || leapYearFrequency === undefined) { throw new Error('CustomLeapYear week calculation requires leapYear, leapYearEndDate, and leapYearFrequency to be defined'); } return new custom_leap_year_1.CustomLeapYearStrategy(leapYear, leapYearEndDate, leapYearFrequency); } } }; Calendar.prototype.getAdjustedGregorianYear = function (year) { if (this.options.lastMonthOfYear !== types_1.LastMonthOfYear.December) { return year + 1; } else { return year; } }; return Calendar; }());