datemapper
Version:
A lightweight date utility for format conversion, validation, and date manipulation.
68 lines (60 loc) • 2.67 kB
text/typescript
import * as moment from "moment-timezone";
import validateDate from "./validate-date";
import { TIncrementType } from "./types";
/**
* Increments a date by a specified amount based on the increment type.
* Ensures timezone adjustments are correctly applied.
*
* @param date - The starting date to be incremented.
* @param incrementType - The type of increment to apply ('day', 'month', 'hour', 'year', 'week').
* @param timezone - The timezone to use for the new date.
* @returns A new Date object incremented according to the specified type.
* @throws Will throw an error if an invalid increment type is provided.
*/
const incrementDate = (date: Date, incrementType: TIncrementType, timezone: string): Date => {
const momentDate = moment.tz(date, timezone); // Apply timezone
switch (incrementType) {
case "day":
return momentDate.add(1, "day").startOf("day").toDate();
case "month":
return momentDate.add(1, "month").startOf("month").toDate();
case "hour":
return momentDate.add(1, "hour").startOf("hour").toDate();
case "year":
return momentDate.add(1, "year").startOf("year").toDate();
case "week":
return momentDate.add(1, "week").startOf("week").toDate(); // Add 7 days for a week
default:
throw new Error("Invalid increment type");
}
};
/**
* Generates an array of dates between two specified dates, incremented by a given type and formatted.
* Ensures all dates are correctly adjusted for the specified timezone.
*
* @param from - The start date in string format (YYYY-MM-DD).
* @param to - The end date in string format (YYYY-MM-DD).
* @param ic - The type of increment to apply between the start and end dates.
* @param timezone - The timezone in which the dates should be interpreted (default: "UTC").
* @param out - The moment.js format string to be applied to each date in the output array. Defaults to 'YYYY-MM-DD'.
* @returns An array of strings representing dates between the start and end dates, formatted according to `out`.
*/
const datesBetween = (
from: string,
to: string,
ic: TIncrementType,
out = "YYYY-MM-DD",
timezone = "UTC"
): string[] => {
const { from: fromDate, to: toDate } = validateDate({ from, to }, timezone);
const array: string[] = [];
// Convert fromDate to moment object with timezone
let currentDate = moment.tz(fromDate, timezone);
// Loop until we reach the end date
while (currentDate.isSameOrBefore(moment.tz(toDate, timezone))) {
array.push(currentDate.format(out));
currentDate = moment.tz(incrementDate(currentDate.toDate(), ic, timezone), timezone);
}
return array;
};
export default datesBetween;