UNPKG

daily-toolset

Version:

A lightweight, versatile collection of TypeScript utility functions for everyday development needs. Simplify and streamline your Node.js, React, and Next.js projects with a powerful suite of well-organized helpers for strings, arrays, dates, objects, and

710 lines (709 loc) 27.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatDate = formatDate; exports.getDayName = getDayName; exports.getDay = getDay; exports.getMonthName = getMonthName; exports.getMonth = getMonth; exports.getYear = getYear; exports.formatTime = formatTime; exports.formatDateTime = formatDateTime; exports.timeAgo = timeAgo; exports.addDays = addDays; exports.addMonths = addMonths; exports.addYears = addYears; exports.addHours = addHours; exports.addMinutes = addMinutes; exports.addSeconds = addSeconds; exports.daysInMonth = daysInMonth; exports.isToday = isToday; exports.isTomorrow = isTomorrow; exports.isYesterday = isYesterday; exports.isPast = isPast; exports.isFuture = isFuture; exports.daysBetween = daysBetween; exports.hoursBetween = hoursBetween; exports.minutesBetween = minutesBetween; exports.daysSince = daysSince; exports.daysUntil = daysUntil; exports.hoursSince = hoursSince; exports.hoursUntil = hoursUntil; exports.dayOfYear = dayOfYear; exports.weekOfYear = weekOfYear; exports.isValidDate = isValidDate; exports.ageFromDOB = ageFromDOB; /** * Formats a given date object into a specified date format string. * * @param date The date object to format. If a string is passed, it must be a valid * date in the format "YYYY-MM-DD". If null is passed, the function * will format the current date. * @param opts An object containing options for the formatter. The following * options are available: * - format: The desired output format. Defaults to "DD/MM/YYYY". * - monthFormat: The format for the month. Defaults to "short". Can * be either "short" or "long". If "long", the full month name * will be used. If "short", the abbreviated month name will be * used. * - dayFormat: The format for the day. Defaults to "short". Can * be either "short" or "long". If "long", the full day name * will be used. If "short", the abbreviated day name will be * used. * @returns A string representing the formatted date. * * Supported formats include: * - "YYYY-MM-DD" * - "DD-MM-YYYY" * - "MM-DD-YYYY" * - "YYYY/MM/DD" * - "DD/MM/YYYY" * - "Month DD, YYYY" * - "DD Month YYYY" * - "YYYY" * - "MM" * - "mm" * - "M" * - "DD" * - "dd" * - "D" */ function formatDate(date = new Date(), { format = "DD/MM/YYYY", monthFormat = "short", dayFormat = "short", } = {}) { var _a, _b; if (date === null) { date = new Date(); } if (typeof date === "string" && !isValidDate(date)) { throw new Error(`Invalid date string provided: "${date}". Expected format: YYYY-MM-DD or similar.`); } if (typeof date === "string" && isValidDate(date)) { date = new Date(date); } if (!(date instanceof Date)) { throw new TypeError("Expected a Date object, but received " + typeof date); } const year = date.getFullYear(); const month = date.getMonth(); // 0-based index const day = date.getDate(); const weekDay = date.getDay(); // Zero-padded values const paddedMonth = String(month + 1).padStart(2, "0"); const paddedDay = String(day).padStart(2, "0"); // Names for months and days const monthNames = { long: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ], short: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ], }; const dayNames = { long: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ], short: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], }; const monthName = ((_a = monthNames[monthFormat]) === null || _a === void 0 ? void 0 : _a[month]) || ""; const dayName = ((_b = dayNames[dayFormat]) === null || _b === void 0 ? void 0 : _b[weekDay]) || ""; // Switch for format selection switch (format) { case "YYYY-MM-DD": return `${year}-${paddedMonth}-${paddedDay}`; case "DD-MM-YYYY": return `${paddedDay}-${paddedMonth}-${year}`; case "MM-DD-YYYY": return `${paddedMonth}-${paddedDay}-${year}`; case "YYYY/MM/DD": return `${year}/${paddedMonth}/${paddedDay}`; case "DD/MM/YYYY": return `${paddedDay}/${paddedMonth}/${year}`; case "Month DD, YYYY": return `${monthName} ${day}, ${year}`; case "DD Month YYYY": return `${day} ${monthName} ${year}`; case "YYYY": return `${year}`; case "MM": return `${paddedMonth}`; case "mm": return `${month + 1}`; case "M": return `${monthName}`; case "DD": return `${paddedDay}`; case "dd": return `${day}`; case "D": return `${dayName}`; default: throw new Error(`Unsupported format: "${format}".`); } } /** * Retrieves the day of the week from a given date as a string. * * @param {Date | FixedDate | null} date - The date to retrieve the day from. Defaults to the current date. * @param {"short" | "long"} [format="short"] - The format of the day name to return. Defaults to "short". * @returns {string} The day name as a string (e.g. "Mon" or "Monday"). */ function getDayName(date = new Date(), format = "short") { const day = formatDate(date, { format: "D", dayFormat: format }); return day; } /** * Retrieves the day of the month from a given date as a zero-padded two-digit string. * * @param {Date | FixedDate | null} date - The date to retrieve the day from. Defaults to the current date. * @returns {string} A two-digit string representing the day of the month (01-31). */ function getDay(date = new Date()) { const day = formatDate(date, { format: "DD" }); return day; } /** * Retrieves the month from a given date as a formatted string. * * @example * const result = getMonthName(); * console.log(result); * // Output: "Jan" (or the current month) * * const result = getMonthName(new Date(), "long"); * console.log(result); * // Output: "August" (or the current month) * * @param {Date | FixedDate | null} [date] - The date to retrieve the month from. * @param {FormatDateParams["monthFormat"]} [format] - The format of the month string. * @returns {string} The month as a formatted string. */ function getMonthName(date = new Date(), format = "short") { const month = formatDate(date, { format: "M", monthFormat: format }); return month; } /** * Retrieves the month from a given date as a formatted string. * * This function takes a Date object, a FixedDate object, or null and returns * the month in the specified format. If no date is provided, the current date is used. * * @param {Date | FixedDate | null} [date=new Date()] - The date from which to extract the month. * @param {FormatDateParams["monthFormat"]} [format="short"] - The format to use for the month. * @returns {string} The month extracted from the date, formatted as a number. */ function getMonth(date = new Date()) { const month = formatDate(date, { format: "MM" }); return Number(month); } /** * Retrieves the year from a given date as a string. * * This function takes a Date object, a FixedDate object, or null and returns * the year in the "YYYY" format. If no date is provided, the current date is used. * * @param {Date | FixedDate | null} [date=new Date()] - The date from which to extract the year. * @returns {string} The year extracted from the date, formatted as a string. */ function getYear(date = new Date()) { const year = formatDate(date, { format: "YYYY" }); return Number(year); } /** * Formats a `Date` object into a readable time string according to the given format. * * The following formats are supported: * * - `HH:mm:ss` (24-hour format with seconds) * - `HH:mm` (24-hour format without seconds) * - `hh:mmA` (12-hour format with AM/PM) * - `hh:mm:ssA` (12-hour format with seconds and AM/PM) * - `HH:mm:ss.SSS` (24-hour format with milliseconds) * * If an unsupported format string is provided, an error will be thrown with a message indicating the unsupported format. * * @param {Date} date The `Date` object to format. * @param {string} [format="hh:mmA"] The format string to use. * @returns {string} A `string` representing the formatted time. * @throws {TypeError} If the `date` parameter is not a `Date` object. * @throws {Error} If the `format` parameter is not a supported format string. */ function formatTime(date = new Date(), { format = "hh:mmA" } = {}) { if (!(date instanceof Date)) { throw new TypeError("Expected a Date object, but received " + typeof date); } const hours = String(date.getHours()).padStart(2, "0"); const minutes = String(date.getMinutes()).padStart(2, "0"); const seconds = String(date.getSeconds()).padStart(2, "0"); const period = Number(hours) < 12 ? "AM" : "PM"; switch (format) { case "HH:mm:ss": return `${hours}:${minutes}:${seconds}`; case "HH:mm": return `${hours}:${minutes}`; case "hh:mmA": const hours12 = hours === "00" ? "12" : String(Number(hours) % 12).padStart(2, "0"); return `${hours12}:${minutes}${period}`; case "hh:mm:ssA": const hours12Full = hours === "00" ? "12" : String(Number(hours) % 12).padStart(2, "0"); return `${hours12Full}:${minutes}:${seconds}${period}`; case "HH:mm:ss.SSS": const milliseconds = String(date.getMilliseconds()).padStart(3, "0"); return `${hours}:${minutes}:${seconds}.${milliseconds}`; default: throw new Error("Unsupported format: " + format); } } /** * Formats a `Date` object into a string combining both date and time according to specified formats. * * This function allows customization of the date and time formats and returns a single string * that includes both, separated by a specified separator. * * @param {Date} date - The `Date` object to format. * @param {string} [dateFormat="YYYY-MM-DD"] - The format string for the date portion. * @param {string} [timeFormat="hh:mmA"] - The format string for the time portion. * @param {string} [seperator=" "] - The separator to use between the formatted date and time. * @returns {string} A `string` representing the formatted date and time. * @throws {TypeError} If the `date` parameter is not a `Date` object. */ function formatDateTime(date = new Date(), { dateFormat = "DD/MM/YYYY", timeFormat = "hh:mmA", seperator = " | ", } = {}) { if (!(date instanceof Date)) { throw new TypeError("Expected a Date object, but received " + typeof date); } const formattedDate = formatDate(date, { format: dateFormat }); const formattedTime = formatTime(date, { format: timeFormat }); return `${formattedDate}${seperator}${formattedTime}`; } /** * Returns a human-readable string representing the time elapsed since the given date. * * This function takes a date and calculates the time difference between the current * time and the given date. It returns a string representing the time elapsed in a * human-readable format such as "a few seconds ago", "1 minute ago", or "2 hours ago". * If the difference is in days, weeks, months, or years, it returns the corresponding * string format. * * @param {Date | null | undefined} date - The date to calculate the time elapsed from. * @returns {string} - A human-readable string representing the time elapsed since the given date. * @throws {Error} - Throws an error if the date is null, undefined, or in the future. */ function timeAgo(date) { if (date === null || date === undefined) { throw new Error("date is null or undefined"); } const diff = Date.now() - date.getTime(); const seconds = Math.floor(diff / 1000); if (seconds < 0) { throw new Error("date is in the future"); } if (seconds < 60) return `a few seconds ago`; const minutes = Math.floor(seconds / 60); if (minutes < 60) return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`; const hours = Math.floor(minutes / 60); if (hours < 24) return `${hours} ${hours === 1 ? "hour" : "hours"} ago`; const days = Math.floor(hours / 24); if (days < 7) return `${days} ${days === 1 ? "day" : "days"} ago`; const weeks = Math.floor(days / 7); if (weeks < 4) return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`; const months = Math.floor(days / 30); // approximate month if (months < 12) return `${months} ${months === 1 ? "month" : "months"} ago`; const years = Math.floor(days / 365); // approximate year return `${years} ${years === 1 ? "year" : "years"} ago`; } /** * Adds the given number of days to the given date and returns a new Date object. * * @param {number} days - The number of days to add to the date. * @param {Date} [date=new Date()] - The date to add the days to. Defaults to the current date. * @returns {Date} - A new Date object with the given number of days added. */ function addDays(days, date = new Date()) { const newDate = new Date(date); newDate.setDate(newDate.getDate() + days); return newDate; } /** * Adds the given number of months to the given date and returns a new Date object. * * @param {number} months - The number of months to add to the date. * @param {Date} [date=new Date()] - The date to add the months to. Defaults to the current date. * @returns {Date} - A new Date object with the given number of months added. */ function addMonths(months, date = new Date()) { const newDate = new Date(date); newDate.setMonth(newDate.getMonth() + months); return newDate; } /** * Adds the given number of years to the given date and returns a new Date object. * * @param {number} years - The number of years to add to the date. * @param {Date} [date=new Date()] - The date to add the years to. Defaults to the current date. * @returns {Date} - A new Date object with the given number of years added. */ function addYears(years, date = new Date()) { const newDate = new Date(date); newDate.setFullYear(newDate.getFullYear() + years); return newDate; } /** * Adds the given number of hours to the given date and returns a new Date object. * * @param {number} hours - The number of hours to add to the date. * @param {Date} [date=new Date()] - The date to add the hours to. Defaults to the current date. * @returns {Date} - A new Date object with the given number of hours added. */ function addHours(hours, date = new Date()) { const newDate = new Date(date); newDate.setHours(newDate.getHours() + hours); return newDate; } /** * Adds the given number of minutes to the given date and returns a new Date object. * * @param {number} minutes - The number of minutes to add to the date. * @param {Date} [date=new Date()] - The date to add the minutes to. Defaults to the current date. * @returns {Date} - A new Date object with the given number of minutes added. */ function addMinutes(minutes, date = new Date()) { const newDate = new Date(date); newDate.setMinutes(newDate.getMinutes() + minutes); return newDate; } /** * Adds the specified number of seconds to a given date and returns a new Date object. * * @param {number} seconds - The number of seconds to add to the date. * @param {Date} [date=new Date()] - The date to which the seconds will be added. Defaults to the current date. * @returns {Date} A new Date object with the specified number of seconds added. */ function addSeconds(seconds, date = new Date()) { const newDate = new Date(date); newDate.setSeconds(newDate.getSeconds() + seconds); return newDate; } /** * Retrieves the number of days in a given month. * * This function takes a Date object and returns the number of days in its * corresponding month. If no Date object is provided, it defaults to the * current month. * * @param {Date} [date=new Date()] - The date to retrieve the days in month from. * @returns {number} The number of days in the month. */ function daysInMonth(date = new Date()) { const firstDay = new Date(date.getFullYear(), date.getMonth(), 1); const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0); return Math.ceil((lastDay.getTime() - firstDay.getTime()) / (1000 * 60 * 60 * 24) + 1); } /** * Returns true if the given date is today, false otherwise. * * @param {Date} date The date to check. * @returns {boolean} True if the given date is today. */ function isToday(date) { if (!date || isNaN(date.getTime())) return false; const today = new Date(); return (date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear()); } /** * Returns true if the given date is tomorrow, false otherwise. * * @param {Date} date The date to check. * @returns {boolean} True if the given date is tomorrow. */ function isTomorrow(date) { if (!date || isNaN(date.getTime())) return false; const today = new Date(); today.setDate(today.getDate() + 1); return (date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear()); } /** * Checks if a given date is yesterday. * * This function determines whether the provided date corresponds to the day * before the current date. It returns true if the date is yesterday, otherwise * it returns false. * * @param {Date} date - The date to check. * @returns {boolean} - `true` if the date is yesterday, `false` otherwise. */ function isYesterday(date) { if (!date || isNaN(date.getTime())) return false; const today = new Date(); today.setDate(today.getDate() - 1); return (date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear()); } /** * Checks if a given date is in the past. * * Takes a Date object and determines if it is earlier than the current date. * Returns a boolean indicating whether the date is in the past. * * @param {Date} date The date to check. * @param {IsPastOptions} options Configuration options * @param {boolean} [options.includeTime=true] Whether to include time in the comparison * @returns {boolean} `true` if the date is in the past. */ function isPast(date, options = { includeTime: true }) { if (!date || isNaN(date.getTime())) return false; const today = new Date(); if (!options.includeTime) { return (new Date(date.getFullYear(), date.getMonth(), date.getDate()) < new Date(today.getFullYear(), today.getMonth(), today.getDate())); } return date < today; } /** * Checks if a given date is in the future. * * Takes a Date object and determines if it is later than the current date. * Returns a boolean indicating whether the date is in the future. * * @param {Date} date The date to check. * @param {IsFutureOptions} options Configuration options * @param {boolean} [options.includeTime=true] Whether to include time in the comparison * @returns {boolean} `true` if the date is in the future. */ function isFuture(date, options = { includeTime: true }) { if (!date || isNaN(date.getTime())) return false; const today = new Date(); if (!options.includeTime) { return (new Date(date.getFullYear(), date.getMonth(), date.getDate()) > new Date(today.getFullYear(), today.getMonth(), today.getDate())); } return date > today; } /** * Returns the number of days between two dates. * * This function takes two dates and calculates the number of days * between them. It returns the difference in days as an integer. * * @param {Date} date1 - The first date to compare. * @param {Date} date2 - The second date to compare. * @returns {number} - The number of days between the two dates. */ function daysBetween(date1, date2) { if (!date1 || !date2 || isNaN(date1.getTime()) || isNaN(date2.getTime())) return 0; const timeDiff = Math.abs(date1.getTime() - date2.getTime()); const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); return diffDays; } /** * Returns the number of hours between two dates. * * This function takes two dates and calculates the number of hours * between them. The returned value is an integer and is always * positive (i.e., the order of the dates does not matter). */ function hoursBetween(date1, date2) { if (!date1 || !date2 || isNaN(date1.getTime()) || isNaN(date2.getTime())) return 0; const timeDiff = Math.abs(date1.getTime() - date2.getTime()); const diffHours = Math.ceil(timeDiff / (1000 * 3600)); return diffHours; } /** * Returns the number of minutes between two dates. * * This function takes two dates and calculates the number of minutes * between them. It returns the difference in minutes as an integer. * * @param {Date} date1 - The first date to compare. * @param {Date} date2 - The second date to compare. * @returns {number} - The number of minutes between the two dates. */ function minutesBetween(date1, date2) { if (!date1 || !date2 || isNaN(date1.getTime()) || isNaN(date2.getTime())) return 0; const timeDiff = Math.abs(date1.getTime() - date2.getTime()); const diffMinutes = Math.ceil(timeDiff / (1000 * 60)); return diffMinutes; } /** * Returns the number of days since the given date. * * This function takes a date and calculates the number of days that have * passed since that date. If the given date is in the future, it returns 0. * * @param {Date} date - The date to calculate the number of days since. * @returns {number} - The number of days since the given date. */ function daysSince(date) { if (!date || isNaN(date.getTime())) return 0; const today = new Date(); if (date >= today) return 0; const timeDiff = Math.abs(today.getTime() - date.getTime()); const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); return diffDays; } /** * Returns the number of days until the given date from today. * * @param {Date} date - The date to calculate the number of days until. * @returns {number} - The number of days until the given date from today. * @throws {Error} - Throws an error if the date is null, undefined, or in the past. */ function daysUntil(date) { if (!date || isNaN(date.getTime())) return 0; const today = new Date(); if (date <= today) return 0; const timeDiff = Math.abs(date.getTime() - today.getTime()); const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); return diffDays; } /** * Calculates the number of hours since the given date. * * @param {Date} date - The date to calculate the hours since. * @returns {number} The number of hours since the given date. */ function hoursSince(date) { if (!date || isNaN(date.getTime())) return 0; const today = new Date(); if (date >= today) return 0; const timeDiff = Math.abs(today.getTime() - date.getTime()); const diffHours = Math.ceil(timeDiff / (1000 * 3600)); return diffHours; } /** * Calculates the number of hours until the given date. * * @param {Date} date - The date to calculate the hours until. * @returns {number} The number of hours until the given date. */ function hoursUntil(date) { if (!date || isNaN(date.getTime())) return 0; const today = new Date(); if (date <= today) return 0; const timeDiff = Math.abs(date.getTime() - today.getTime()); const diffHours = Math.ceil(timeDiff / (1000 * 3600)); return diffHours; } /** * Retrieves the day of the year from a given date. * * @param {Date | FixedDate | null} date - The date to retrieve the day from. Defaults to the current date. * @returns {number} The day of the year (1-365) as per ISO 8601. */ function dayOfYear(date = new Date()) { const start = new Date(date.getFullYear(), 0, 0); const diff = date.getTime() - start.getTime(); const oneDay = 1000 * 60 * 60 * 24; const day = Math.floor(diff / oneDay); return day; } /** * Retrieves the week of the year from a given date. * * @param {Date | FixedDate | null} date - The date to retrieve the week from. Defaults to the current date. * @returns {number} The week of the year (1-52) as per ISO 8601. */ function weekOfYear(date = new Date()) { const start = new Date(date.getFullYear(), 0, 1); const diff = date.getTime() - start.getTime(); const oneDay = 1000 * 60 * 60 * 24; const day = Math.floor(diff / oneDay); const week = Math.floor(day / 7); return week + 1; } /** * Validates if the provided string is a valid ISO date. * * This function checks if a given string matches the ISO date format * using a regular expression. It then attempts to parse it into a * JavaScript Date object to ensure it represents a valid date. * * @param {string} value - The string to validate as a date. * @returns {boolean} - True if the string is a valid date, false otherwise. */ function isValidDate(value) { if (typeof value !== "string") return false; const isoDateRegex = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z)?)?$/; if (!isoDateRegex.test(value)) return false; const date = new Date(value); return !isNaN(date.getTime()); } /** * Extracts the years, months, and days from a given date of birth. * * This function takes a Date object and returns an object with the years, * months, and days properties. * * @param {Date} dateOfBirth - The date of birth to extract the years, months, and days from. * @returns {object} An object with the years, months, and days properties. */ function ageFromDOB(dateOfBirth) { if (typeof dateOfBirth === "string" && !isValidDate(dateOfBirth)) { throw new Error(`Invalid date string provided: "${dateOfBirth}". Expected format: YYYY-MM-DD or similar.`); } if (typeof dateOfBirth === "string" && isValidDate(dateOfBirth)) { dateOfBirth = new Date(dateOfBirth); } if (!(dateOfBirth instanceof Date)) { throw new TypeError("Expected a Date object, but received " + typeof dateOfBirth); } const today = new Date(); const years = today.getFullYear() - dateOfBirth.getFullYear(); const months = today.getMonth() - dateOfBirth.getMonth(); const days = today.getDate() - dateOfBirth.getDate(); return { years, months, days }; }