UNPKG

@dvsa/appdev-api-common

Version:

Utils library for common API functionality

274 lines (273 loc) 8.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DateTime = void 0; const dayjs_1 = __importDefault(require("dayjs")); const customParseFormat_1 = __importDefault(require("dayjs/plugin/customParseFormat")); const timezone_1 = __importDefault(require("dayjs/plugin/timezone")); const utc_1 = __importDefault(require("dayjs/plugin/utc")); /** * DateTime utility class for handling dates with UK timezone support */ class DateTime { instance; static UKLocalDateTimeFormat = "DD/MM/YYYY HH:mm:ss"; static UKLocalDateFormat = "DD/MM/YYYY"; static UK_TIMEZONE = "Europe/London"; /** * Creates a new DateTime instance * @param sourceDateTime - Initial date/time (string, Date, or another DateTime) * @param format - Optional format string for parsing string dates */ constructor(sourceDateTime, format = undefined) { // Set up dayjs plugins dayjs_1.default.extend(customParseFormat_1.default); dayjs_1.default.extend(timezone_1.default); dayjs_1.default.extend(utc_1.default); if (sourceDateTime === undefined || sourceDateTime === null) { // For current time, directly get the UK time but preserve the timezone this.instance = (0, dayjs_1.default)().tz(DateTime.UK_TIMEZONE); } else if (typeof sourceDateTime === "string" || sourceDateTime instanceof Date) { // For string inputs, PRESERVE THE ORIGINAL TIME without timezone conversion // This is essential for test consistency if (format) { this.instance = (0, dayjs_1.default)(sourceDateTime, format); } else { this.instance = (0, dayjs_1.default)(sourceDateTime); } } else if (sourceDateTime instanceof DateTime) { // Clone a DateTime instance this.instance = sourceDateTime.instance.clone(); } else { throw new Error("Invalid date input"); } } /** * Converts to a JavaScript Date object * @returns Date object */ toDate() { return this.instance.toDate(); } /** * Creates a new DateTime instance from a date source * @param sourceDateTime - Source date/time * @param format - Optional format string for parsing * @returns New DateTime instance or null if source is null */ static at(sourceDateTime, format = undefined) { if (!sourceDateTime) { return null; } return new DateTime(sourceDateTime, format); } /** * Formats a date in UK local date time format (DD/MM/YYYY HH:mm:ss) * @param sourceDateTime - Source date/time * @returns Formatted string or null if source is null */ static StandardUkLocalDateTimeAdapter(sourceDateTime) { return (DateTime.at(sourceDateTime)?.format(DateTime.UKLocalDateTimeFormat) || null); } /** * Formats a date in UK local date format (DD/MM/YYYY) * @param sourceDateTime - Source date/time * @returns Formatted string or null if source is null */ static StandardUkLocalDateAdapter(sourceDateTime) { return (DateTime.at(sourceDateTime)?.format(DateTime.UKLocalDateFormat) || null); } /** * Adds time to this DateTime instance (mutable operation) * @param amount - Amount to add * @param unit - Unit of time (day, month, year, etc.) * @returns This instance for chaining */ add(amount, unit) { this.instance = this.instance.add(amount, unit); return this; } /** * Subtracts time from this DateTime instance (mutable operation) * @param amount - Amount to subtract * @param unit - Unit of time (day, month, year, etc.) * @returns This instance for chaining */ subtract(amount, unit) { this.instance = this.instance.subtract(amount, unit); return this; } /** * Formats the date with a custom format string * @param formatString - Format pattern * @returns Formatted date string */ format(formatString) { return this.instance.format(formatString); } /** * Gets the day of week (0-6, Sunday is 0) * @returns Day of week */ day() { return this.instance.day(); } /** * Sets the date to the start of a specified unit (mutable operation) * @param unit - Unit of time (day, month, year, etc.) * @returns This instance for chaining */ startOf(unit) { this.instance = this.instance.startOf(unit); return this; } /** * Converts to string in UK date time format * @returns Formatted date string */ toString() { return this.format(DateTime.UKLocalDateTimeFormat); } /** * Gets ISO string representation * @returns ISO format string */ toISOString() { return this.instance.toISOString(); } /** * Calculates the difference between dates * @param targetDate - Target date to compare with * @param unit - Unit for the difference calculation * @param precise - Whether to return decimal result * @returns Difference in specified units */ diff(targetDate, unit, precise) { const date = new DateTime(targetDate); return this.instance.diff(date.instance, unit, precise); } /** * Calculates the difference in days * @param targetDate - Target date to compare with * @returns Difference in days */ daysDiff(targetDate) { const date = new DateTime(targetDate); return this.instance .startOf("day") .diff(date.instance.startOf("day"), "day"); } /** * Calculates duration from this date to target * @param targetDate - Target date * @param unit - Unit for duration calculation * @returns Duration in specified units */ compareDuration(targetDate, unit) { const date = new DateTime(targetDate); return date.instance.diff(this.instance, unit); } /** * Checks if the date is valid * @returns True if valid date */ isValid() { return this.instance.isValid(); } /** * Checks if this date is before the target date * @param targetDate - Target date to compare with * @returns True if this date is before target */ isBefore(targetDate) { const date = new DateTime(targetDate); return this.instance.isBefore(date.instance); } /** * Checks if this date is after the target date * @param targetDate - Target date to compare with * @returns True if this date is after target */ isAfter(targetDate) { const date = new DateTime(targetDate); return this.instance.isAfter(date.instance); } /** * Checks if this date is between start and end dates * @param startDate - Start date of range * @param endDate - End date of range * @returns True if date is between start and end */ isBetween(startDate, endDate) { const start = new DateTime(startDate); const end = new DateTime(endDate); return (this.instance.isAfter(start.instance) && this.instance.isBefore(end.instance)); } /** * Sets the timezone (mutable operation) * @param tz - Timezone identifier * @returns This instance for chaining */ setTimezone(tz) { this.instance = this.instance.tz(tz); return this; } /** * Converts to UK timezone (mutable operation) * @returns This instance for chaining */ toUKTime() { this.instance = this.instance.tz(DateTime.UK_TIMEZONE); return this; } /** * Gets the hour component * @returns Hour (0-23) */ getHour() { return this.instance.hour(); } /** * Gets the minute component * @returns Minute (0-59) */ getMinute() { return this.instance.minute(); } /** * Gets the second component * @returns Second (0-59) */ getSecond() { return this.instance.second(); } /** * Creates a clone of this DateTime * @returns New DateTime instance with the same date/time */ clone() { return new DateTime(this); } /** * Provides debug information about this DateTime * @returns Object with diagnostic information */ debug() { return { formatted: this.format("DD/MM/YYYY HH:mm:ss"), isoString: this.toISOString(), hour: this.getHour(), utcOffset: this.instance.utcOffset(), }; } } exports.DateTime = DateTime;