sainsburys-date
Version:
Basic functions to convert a Date object into Sainsbury's financial calendar components
85 lines (84 loc) • 2.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const EPOCH_YEAR = 1970;
const EPOCH_DAY_OFFSET = 129; // Days between 1970-01-01 (Date(0)) and the theoretical 1970 P1 W1
const MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
const QUARTERS_IN_YEAR = 4;
const PERIODS_IN_YEAR = 13;
const DAYS_IN_PERIOD = 28;
const DAYS_IN_YEAR = PERIODS_IN_YEAR * DAYS_IN_PERIOD;
const DAYS_IN_WEEK = 7;
const PERIODS_UP_TO_QUARTER = [0, 3, 6, 10];
function fromDate(date) {
if (!date) {
return undefined;
}
const daysBetween = new Date(date).getTime() / MILLIS_IN_DAY - EPOCH_DAY_OFFSET;
const days = Math.ceil(daysBetween) % DAYS_IN_YEAR; // Number of days into the financial year
const period = Math.floor(days / DAYS_IN_PERIOD) + 1;
let quarter;
switch (period) {
case 1:
case 2:
case 3:
quarter = 1;
break;
case 4:
case 5:
case 6:
quarter = 2;
break;
case 7:
case 8:
case 9:
case 10:
quarter = 3;
break;
case 11:
case 12:
case 13:
quarter = 4;
break;
default:
}
return {
year: Math.floor(daysBetween / DAYS_IN_YEAR) + EPOCH_YEAR,
quarter,
period,
week: Math.floor((days % DAYS_IN_PERIOD) / DAYS_IN_WEEK) + 1,
};
}
function toDate(options) {
let days = EPOCH_DAY_OFFSET;
if (options.year) {
const yearOpt = options.year;
days += (yearOpt - EPOCH_YEAR) * DAYS_IN_YEAR;
}
if (options.quarter) {
const quarterOpt = options.quarter - 1;
days += Math.floor(quarterOpt / QUARTERS_IN_YEAR) * DAYS_IN_YEAR;
days += (PERIODS_UP_TO_QUARTER[quarterOpt % QUARTERS_IN_YEAR] || 0) * DAYS_IN_PERIOD;
}
if (options.period) {
const periodOpt = options.period - 1;
days += periodOpt * DAYS_IN_PERIOD;
}
if (options.week) {
const weekOpt = options.week - 1;
days += weekOpt * DAYS_IN_WEEK;
}
if (options.day) {
const dayOpt = options.day - 1;
days += dayOpt;
}
return new Date(days * MILLIS_IN_DAY);
}
exports.default = {
QUARTERS_IN_YEAR,
PERIODS_IN_YEAR,
DAYS_IN_PERIOD,
DAYS_IN_YEAR,
fromDate,
toDate,
convert: fromDate, // For backwards compatibility
};