rpg-calendar
Version:
Low level library for working with RPG/Fantasy dates
210 lines • 20.5 kB
JavaScript
"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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