@georgevie/period-sequence
Version:
High-performance TypeScript library for time period manipulation with immutable design and enterprise-grade performance
212 lines • 10.3 kB
JavaScript
"use strict";
/**
* Named constructors for Period creation optimized for date-only operations
* All constructors work with day-level precision and normalize to midnight UTC
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PeriodConstructors = void 0;
const Period_1 = require("../core/Period");
const types_1 = require("../core/types");
const DurationInterval_1 = require("../duration/DurationInterval");
var PeriodConstructors;
(function (PeriodConstructors) {
/**
* Create period from start and end dates (most common constructor)
* Dates are automatically normalized to midnight UTC for date-only operations
*/
function fromDates(start, end, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
return new Period_1.Period(start, end, bounds);
}
PeriodConstructors.fromDates = fromDates;
/**
* Create period from month (optimized for date-only operations)
* Returns period covering the entire month at day-level precision
*/
function fromMonth(year, month, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
// Optimization: Use timestamps directly (already midnight UTC)
const startTime = Date.UTC(year, month - 1, 1);
const endTime = Date.UTC(year, month, 1);
return new Period_1.Period(startTime, endTime, bounds);
}
PeriodConstructors.fromMonth = fromMonth;
/**
* Create period from year (optimized for date-only operations)
* Returns period covering the entire year at day-level precision
*/
function fromYear(year, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
// Optimization: Use timestamps directly (already midnight UTC)
const startTime = Date.UTC(year, 0, 1);
const endTime = Date.UTC(year + 1, 0, 1);
return new Period_1.Period(startTime, endTime, bounds);
}
PeriodConstructors.fromYear = fromYear;
/**
* Create period from a single day (optimized for date-only operations)
* Returns a 1-day period for the specified date
*/
function fromDay(date, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const day = typeof date === 'string' ? new Date(date) : date;
// Optimization: Use timestamps directly (already midnight UTC)
const startTime = Date.UTC(day.getUTCFullYear(), day.getUTCMonth(), day.getUTCDate());
const endTime = Date.UTC(day.getUTCFullYear(), day.getUTCMonth(), day.getUTCDate() + 1);
return new Period_1.Period(startTime, endTime, bounds);
}
PeriodConstructors.fromDay = fromDay;
/**
* Create period starting after a specific date (date-only operations)
* Duration is applied at day-level precision, minimum 1 day
*/
function after(start, duration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const startDate = typeof start === 'string' ? new Date(start) : start;
// Ensure minimum 1-day duration for date-only operations
const durationDays = Math.max(1, Math.ceil(duration.milliseconds / 86400000));
const endTime = startDate.getTime() + (durationDays * 86400000);
const endDate = new Date(endTime);
return new Period_1.Period(startDate, endDate, bounds);
}
PeriodConstructors.after = after;
/**
* Create period ending before a specific date (date-only operations)
* Duration is applied at day-level precision, minimum 1 day
*/
function before(end, duration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const endDate = typeof end === 'string' ? new Date(end) : end;
// Ensure minimum 1-day duration for date-only operations
const durationDays = Math.max(1, Math.ceil(duration.milliseconds / 86400000));
const startTime = endDate.getTime() - (durationDays * 86400000);
const startDate = new Date(startTime);
return new Period_1.Period(startDate, endDate, bounds);
}
PeriodConstructors.before = before;
/**
* Create period centered around a specific date (date-only operations)
* Duration is split evenly around the center date, minimum 1 day each side
*/
function around(center, duration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const centerDate = typeof center === 'string' ? new Date(center) : center;
// For date-only operations, ensure at least 1 day on each side
const durationDays = Math.max(2, Math.ceil(duration.milliseconds / 86400000)); // Minimum 2 days total
const halfDurationDays = Math.floor(durationDays / 2);
const startTime = centerDate.getTime() - (halfDurationDays * 86400000);
const endTime = centerDate.getTime() + (halfDurationDays * 86400000);
const startDate = new Date(startTime);
const endDate = new Date(endTime);
return new Period_1.Period(startDate, endDate, bounds);
}
PeriodConstructors.around = around;
/**
* Create period from ISO 8601 duration string starting at date
* Combines parsing and construction for efficiency
*/
function fromISO8601(start, isoDuration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const duration = DurationInterval_1.DurationInterval.fromISO8601(isoDuration);
return after(start, duration, bounds);
}
PeriodConstructors.fromISO8601 = fromISO8601;
/**
* Create period from ISO week (yyyy-Www format)
* Optimized with direct UTC calculations
*/
function fromWeek(year, week, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
// ISO week calculation
// Week 1 is the first week with 4 or more days in the new year
const jan4 = new Date(Date.UTC(year, 0, 4));
const jan4Day = jan4.getUTCDay() || 7; // Sunday = 7, Monday = 1
// Start of week 1 (Monday)
const week1Start = new Date(jan4.getTime() - (jan4Day - 1) * 86400000);
// Calculate the target week
const weekStart = new Date(week1Start.getTime() + (week - 1) * 7 * 86400000);
const weekEnd = new Date(weekStart.getTime() + 7 * 86400000);
return new Period_1.Period(weekStart.getTime(), weekEnd.getTime(), bounds);
}
PeriodConstructors.fromWeek = fromWeek;
/**
* Create period from quarter (1-4)
* Optimized with direct UTC calculations
*/
function fromQuarter(year, quarter, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
if (quarter < 1 || quarter > 4) {
throw new Error('Quarter must be between 1 and 4');
}
const startMonth = (quarter - 1) * 3;
const startTime = Date.UTC(year, startMonth, 1);
const endTime = Date.UTC(year, startMonth + 3, 1);
return new Period_1.Period(startTime, endTime, bounds);
}
PeriodConstructors.fromQuarter = fromQuarter;
/**
* Create period from millisecond timestamps (date-only operations)
* Timestamps are normalized to midnight UTC for consistent behavior
*/
function fromTimestamps(startMs, endMs, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
// Optimization: Pass timestamps directly (will be normalized by Period constructor)
return new Period_1.Period(startMs, endMs, bounds);
}
PeriodConstructors.fromTimestamps = fromTimestamps;
/**
* Create period representing today (current date in local timezone)
* Returns a 1-day period for today at date-only precision
*/
function today(bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const now = new Date();
const startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
return new Period_1.Period(startDate, endDate, bounds);
}
PeriodConstructors.today = today;
/**
* Create period representing this week (Monday to Sunday)
* Uses ISO week calculation with date-only precision
*/
function thisWeek(bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const now = new Date();
const currentDay = now.getDay() || 7; // Sunday = 7, Monday = 1
const monday = new Date(now.getTime() - (currentDay - 1) * 86400000);
monday.setHours(0, 0, 0, 0);
const sunday = new Date(monday.getTime() + 7 * 86400000);
return new Period_1.Period(monday, sunday, bounds);
}
PeriodConstructors.thisWeek = thisWeek;
/**
* Create period representing this month
* Uses current date's month
*/
function thisMonth(bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const now = new Date();
return fromMonth(now.getFullYear(), now.getMonth() + 1, bounds);
}
PeriodConstructors.thisMonth = thisMonth;
/**
* Create period representing this year
* Uses current date's year
*/
function thisYear(bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const now = new Date();
return fromYear(now.getFullYear(), bounds);
}
PeriodConstructors.thisYear = thisYear;
/**
* Create period starting from today with specified duration (date-only operations)
* Uses current date as starting point, duration rounded up to whole days
*/
function fromToday(duration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const startDate = new Date();
const durationDays = Math.max(1, Math.ceil(duration.milliseconds / 86400000));
const endTime = startDate.getTime() + (durationDays * 86400000);
const endDate = new Date(endTime);
return new Period_1.Period(startDate, endDate, bounds);
}
PeriodConstructors.fromToday = fromToday;
/**
* Create period with specified duration starting from given time
* Alias for 'after' with clearer naming
*/
function fromDuration(start, duration, bounds = types_1.Bounds.IncludeStartExcludeEnd) {
const startTime = typeof start === 'number' ? start :
typeof start === 'string' ? new Date(start).getTime() : start.getTime();
const endTime = startTime + duration.milliseconds;
return new Period_1.Period(startTime, endTime, bounds);
}
PeriodConstructors.fromDuration = fromDuration;
})(PeriodConstructors || (exports.PeriodConstructors = PeriodConstructors = {}));
//# sourceMappingURL=PeriodConstructors.js.map