UNPKG

rpg-calendar

Version:

Low level library for working with RPG/Fantasy dates

210 lines 20.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RPGCalendar = void 0; const lib_1 = require("./lib"); const time_1 = require("./lib/time"); class RPGCalendar { constructor(config) { this.config = config; const { yearNameMap = {} } = config; this.isLeapYear = (0, lib_1.isLeapYearBuilder)((config === null || config === void 0 ? void 0 : config.leapYearInterval) || 0, config === null || config === void 0 ? void 0 : config.hasYear0); this.getDaysInYear = (0, lib_1.getDaysInYearBuilder)(config.months, this.isLeapYear); this.getDaysInMonth = (0, lib_1.getDaysInMonthBuilder)(config.months, this.isLeapYear); this.getDaysInWeek = (0, lib_1.getDaysInWeekBuilder)(config.weekdays); this.getYearName = (0, lib_1.getYearNameBuilder)(yearNameMap); this.getWeekDays = () => this.config.weekdays; this.getDayName = (dayOfWeek) => { var _a, _b; return ((_b = (_a = this.config.weekdays) === null || _a === void 0 ? void 0 : _a[dayOfWeek - 1]) === null || _b === void 0 ? void 0 : _b.name) || 'Unknown'; }; this.getMonthName = (month) => { var _a, _b; return ((_b = (_a = this.config.months) === null || _a === void 0 ? void 0 : _a[month - 1]) === null || _b === void 0 ? void 0 : _b.name) || 'Unknown'; }; this.getConfigMonth = (month) => this.config.months[month - 1]; this.getPrevMonthYear = (0, lib_1.getPrevMonthYearBuilder)(config === null || config === void 0 ? void 0 : config.hasYear0, this.config.months); this.getNextMonthYear = (0, lib_1.getNextMonthYearBuilder)(config === null || config === void 0 ? void 0 : config.hasYear0, this.config.months); this.getPrevYear = (0, lib_1.getPrevYearBuilder)(config === null || config === void 0 ? void 0 : config.hasYear0); this.getNextYear = (0, lib_1.getNextYearBuilder)(config === null || config === void 0 ? void 0 : config.hasYear0); this.getExtraDay = (0, lib_1.getExtraDayBuilder)(this.config.months, this.isLeapYear); } // dateStringToRPGDate accepts the date in a more readable format, parses it and returns an RPGCalendarDate object. // dateString resembles the ISO 8601 format but without the fractional seconds: YYYY-MM-DD hh:mm:ss dateStringToRPGDate(dateString) { const dateAndTime = dateString.split(' '); if (dateAndTime.length !== 2) { throw new Error(`${dateString} is not a valid date time string format`); } const dateParts = dateAndTime[0].split('-'); if (dateParts.length !== 3) { throw new Error(`${dateString} does not contain a valid date part`); } const timeParts = dateAndTime[1].split(':'); if (timeParts.length !== 3) { throw new Error(`${dateString} does not contain a valid time part`); } // Assign known values const time = { hour: parseInt(timeParts[0]), minute: parseInt(timeParts[1]), second: parseInt(timeParts[2]) }; const year = parseInt(dateParts[0]); const monthOfYear = parseInt(dateParts[1]); const dayOfMonth = parseInt(dateParts[2]); // Calculate day of week const daysInWeek = this.getDaysInWeek(); const dayMod = dayOfMonth % daysInWeek; const dayOfWeek = dayMod === 0 ? dayOfMonth / daysInWeek : dayMod; return { time, year, dayOfMonth, monthOfYear, dayOfWeek, dayName: this.getDayName(dayOfWeek), inLeapYear: this.isLeapYear(year), monthName: this.getMonthName(monthOfYear), yearName: this.getYearName(year) }; } // epochToDate accepts both a simple day epoch (number of days) or a complex epoch (number of days with the time) epochToDate(epoch) { let epochDay; let time = { hour: 0, minute: 0, second: 0 }; if (typeof epoch === 'string') { const dateParts = epoch.split('-'); if (dateParts.length !== 2) { throw new Error(`${epoch} is not a valid date time epoch format`); } const timeParts = dateParts[1].split(':'); if (timeParts.length !== 3) { throw new Error(`${epoch} is not a valid time format`); } time = { hour: parseInt(timeParts[0]), minute: parseInt(timeParts[1]), second: parseInt(timeParts[2]) }; epochDay = parseInt(dateParts[0]); } else { epochDay = epoch; } // Calculate the year let year = 0; let dayOfYear = epochDay; while (dayOfYear >= this.getDaysInYear(year)) { dayOfYear = dayOfYear - this.getDaysInYear(year); year++; } // Calculate the month of the year let monthOfYear = 1; let dayOfMonth = dayOfYear; while (dayOfMonth > this.getDaysInMonth(monthOfYear, year)) { dayOfMonth = dayOfMonth - this.getDaysInMonth(monthOfYear, year); monthOfYear++; } // Calculate day of week const daysInWeek = this.getDaysInWeek(); const dayMod = dayOfMonth % daysInWeek; const dayOfWeek = dayMod === 0 ? dayOfMonth / daysInWeek : dayMod; const epochDayTime = `${epochDay}-${(0, time_1.getTimeString)(time)}`; return { year, epochDay, epochDayTime, monthOfYear, dayOfMonth, dayOfYear, dayOfWeek, dayName: this.getDayName(dayOfWeek), inLeapYear: this.isLeapYear(year), monthName: this.getMonthName(monthOfYear), yearName: this.getYearName(year), time }; } // createDate is a simple interface that lets you construct a date object. Only the year is required, everything else // defaults (first month, first day, and 00:00:00) createDate(year, month = 1, day = 1, hour = 0, minute = 0, second = 0) { var _a; const startYear = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.hasYear0) ? 0 : 1; // Count the days up to the year let epochDay = 0; for (let y = startYear; y < year; y++) { epochDay += this.getDaysInYear(y); } // Count the days up to the month let dayOfYear = 0; for (let m = 1; m < month; m++) { epochDay += this.getDaysInMonth(m, year); } // Add in the days epochDay += day; dayOfYear += day; // Calculate day of week const daysInWeek = this.getDaysInWeek(); const dayMod = day % daysInWeek; const dayOfWeek = dayMod === 0 ? day / daysInWeek : dayMod; // Setup time const time = { hour, minute, second }; const epochDayTime = `${epochDay}-${(0, time_1.getTimeString)(time)}`; return { year, epochDay, epochDayTime, monthOfYear: month, dayOfMonth: day, dayOfYear, dayOfWeek, dayName: this.getDayName(dayOfWeek), inLeapYear: this.isLeapYear(year), monthName: this.getMonthName(month), yearName: this.getYearName(year), time, extraDay: this.getExtraDay(year, month, day) }; } // getDisplayMonth returns a month object based on the month and year getDisplayMonth(mq) { const { year, month } = mq; // Get the month as it's defined in the configuration const configMonth = this.getConfigMonth(month); // Get the first day of the month so that we can pull off all the information that pertains to the entire month. const firstDayOfMonth = this.createDate(year, month, 1); const { yearName } = firstDayOfMonth; const daysInMonth = this.getDaysInMonth(month, year); const daysInWeek = this.getDaysInWeek(); const weeks = []; for (let d = 1; d <= daysInMonth; d++) { const w = Math.floor((d - 1) / daysInWeek); if (!(weeks === null || weeks === void 0 ? void 0 : weeks[w])) { weeks.push([]); } weeks[w].push(this.createDate(year, month, d)); } return Object.assign(Object.assign({}, configMonth), { weeks, year, yearName, monthOfYear: month, weekdays: this.getWeekDays(), nextMonthQuery: this.getNextMonthYear({ year, month }), prevMonthQuery: this.getPrevMonthYear({ year, month }), nextYearQuery: this.getNextYear({ year, month }), prevYearQuery: this.getPrevYear({ year, month }) }); } // getMonths returns all the months in a year. Useful when displaying a dropdown. getMonths() { return this.config.months; } // getDaySpanFromDate returns a RPGDateSpan with the min and max (start/end) times for the given day. This is useful // when creating queries or defining an event that lasted for an entire day. getDaySpanFromDate(date) { const eh = this.config.hoursInDay - 1; const em = this.config.minutesInHour - 1; const es = this.config.secondsInMinutes - 1; return { start: this.createDate(date.year, date.monthOfYear, date.dayOfMonth), end: this.createDate(date.year, date.monthOfYear, date.dayOfMonth, eh, em, es) }; } } exports.RPGCalendar = RPGCalendar; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUlBHQ2FsZW5kYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvUlBHQ2FsZW5kYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBV0EsK0JBV2U7QUFDZixxQ0FBMkM7QUFFM0MsTUFBYSxXQUFXO0lBaUJ0QixZQUFvQixNQUF5QjtRQUF6QixXQUFNLEdBQU4sTUFBTSxDQUFtQjtRQUMzQyxNQUFNLEVBQUUsV0FBVyxHQUFHLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUVwQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUEsdUJBQWlCLEVBQUMsQ0FBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsZ0JBQWdCLEtBQUksQ0FBQyxFQUFFLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxRQUFRLENBQUMsQ0FBQztRQUNyRixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUEsMEJBQW9CLEVBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFBLDJCQUFxQixFQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFBLHdCQUFrQixFQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBeUIsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQ3BFLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFVLEVBQUUsZUFBQyxPQUFBLENBQUEsTUFBQSxNQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSwwQ0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDLDBD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