Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/shared/DateUtils.ts
T

190 lines
6.8 KiB
TypeScript

import { differenceInDays, format, formatDistanceToNow, startOfDay, startOfMinute, startOfMonth, startOfWeek, startOfYear } from "date-fns";
export type DateFormatType = "YYYY-MM-DD" | "DD-MM-YYYY" | "MM-DD-YYYY" | "diff";
export const DateFormats: { name: string; value: DateFormatType; labelKey: string }[] = [
{ name: "YYYY-MM-DD", value: "YYYY-MM-DD", labelKey: "formats.date.ymd" },
{ name: "DD-MM-YYYY", value: "DD-MM-YYYY", labelKey: "formats.date.dmy" },
{ name: "MM-DD-YYYY", value: "MM-DD-YYYY", labelKey: "formats.date.mdy" },
{ name: "Difference", value: "diff", labelKey: "formats.date.diff" },
];
export type DateDisplay = "ymd" | "ago" | "dm" | "mdy" | "hms" | "ymdhms" | "ymdhmsms";
const coerce = (value: Date | string | null | undefined): Date => {
if (value === null || value === undefined) return new Date();
return value instanceof Date ? value : new Date(value);
};
const fmt = (value: Date | string | null | undefined, pattern: string): string => {
return format(coerce(value), pattern);
};
const dateAgo = (value: Date | string | null | undefined): string => {
const at = coerce(value);
const days = Math.abs(differenceInDays(new Date(), at));
if (days <= 1) {
return formatDistanceToNow(startOfMinute(at), { addSuffix: true });
} else if (days <= 7) {
return formatDistanceToNow(startOfDay(at), { addSuffix: true });
} else if (days <= 30) {
return formatDistanceToNow(startOfWeek(at), { addSuffix: true });
} else if (days <= 30 * 12) {
return formatDistanceToNow(startOfMonth(at), { addSuffix: true });
} else if (days <= 30 * 12 * 2) {
return formatDistanceToNow(startOfYear(at), { addSuffix: true });
} else {
return fmt(at, "yyyy-MM-dd");
}
};
const dateYMD = (value: Date | string | null | undefined): string => fmt(value, "yyyy-MM-dd");
const dateDMY = (value: Date | string | null | undefined): string => fmt(value, "dd-MM-yyyy");
const dateMDY = (value: Date | string | null | undefined): string => fmt(value, "MM-dd-yyyy");
const dateLL = (value: Date | string | null | undefined): string => fmt(value, "yyyy-MM-dd");
const dateYMDHM = (value: Date | string | null | undefined): string => fmt(value, "yyyy-MM-dd HH:mm");
const dateYMDHMS = (value: Date | string | null | undefined): string => fmt(value, "yyyy-MM-dd HH:mm:ss");
const dateYMDHMSMS = (value: Date | string | null | undefined): string => fmt(value, "yyyy-MM-dd HH:mm:ss.SSS");
const dateMonthName = (value: Date | string | null | undefined): string => fmt(value, "MMMM yyyy");
const dateDM = (value: Date | string | null | undefined): string => fmt(value, "d MMM");
const dateMonthDayYear = (value: Date | string | null | undefined): string => fmt(value, "MMMM d, yyyy");
const dateMonthDay = (value: Date | string | null | undefined): string => fmt(value, "MMM d");
const dateHMS = (value: Date | string | null | undefined): string => fmt(value, "HH:mm:ss");
const daysFromDate = (value: Date, days: number) => {
return new Date(new Date().setDate(value.getDate() + days));
};
const diffDays = (a: Date, b: Date) => {
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
return (utc2 - utc1) / _MS_PER_DAY;
};
const add = (value: Date, days: number) => {
return new Date(new Date().setDate(value.getDate() + days));
};
const getMonths = () => {
return ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
};
const getMonthName = (month: number): string => {
const months: string[] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
if (month >= 1 && month <= 12) {
return months[month - 1].substring(0, 3);
}
return "";
};
const isCurrentMonth = (year: number, month: number): boolean => {
const today = new Date();
return today.getFullYear() === year && today.getMonth() + 1 === month;
};
const gteFromFilter = (filter: string, from?: Date) => {
let gte: Date | undefined = undefined;
if (!from) {
from = new Date();
}
if (filter === "all-time") {
gte = undefined;
} else if (filter === "last-24-hours") {
gte = daysFromDate(from, 1 * -1);
} else if (filter === "last-7-days") {
gte = daysFromDate(from, 7 * -1);
} else if (filter === "last-30-days") {
gte = daysFromDate(from, 30 * -1);
} else if (filter === "last-3-months") {
gte = daysFromDate(from, 30 * 3 * -1);
} else if (filter === "last-6-months") {
gte = daysFromDate(from, 30 * 6 * -1);
} else if (filter === "last-year") {
gte = daysFromDate(from, 30 * 12 * -1);
} else if (filter === "year-to-date") {
gte = new Date(from.getFullYear(), 0, 1);
} else if (filter === "month-to-date") {
gte = new Date(from.getFullYear(), from.getMonth(), 1);
} else if (filter === "week-to-date") {
gte = new Date(from.getFullYear(), from.getMonth(), from.getDate() - from.getDay());
} else if (filter === "last-hour") {
gte = new Date(from.getTime() - 60 * 60 * 1000);
} else if (filter === "last-10-minutes") {
gte = new Date(from.getTime() - 10 * 60 * 1000);
}
return gte;
};
const getDuration = ({ start, end, format = "s" }: { start: Date; end: Date; format: "ms" | "s" | "m" | "h" | "d" | "w" | "M" | "y" }) => {
const diff = +new Date(end) - +new Date(start);
const seconds = Math.floor(diff / 1000);
switch (format) {
case "ms":
return diff;
case "s":
return seconds;
case "m":
return Math.floor(seconds / 60);
case "h":
return Math.floor(seconds / 3600);
case "d":
return Math.floor(seconds / 86400);
case "w":
return Math.floor(seconds / 604800);
case "M":
return Math.floor(seconds / 2592000);
case "y":
return Math.floor(seconds / 31536000);
default:
return diff;
}
};
function getDurationInSeconds({ start, end }: { start: Date | null; end: Date | null }) {
if (start && end) {
const diff = +new Date(end) - +new Date(start);
const seconds = Math.floor(diff / 1000);
if (seconds < 60) {
return `${seconds}s`;
} else {
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
}
}
return "-";
}
function getDateStartOfDay(date: Date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
}
function getDateEndOfDay(date: Date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
}
export default {
dateAgo,
dateYMD,
dateDMY,
dateMDY,
dateLL,
dateYMDHM,
dateYMDHMS,
dateYMDHMSMS,
dateMonthName,
dateDM,
dateHMS,
dateMonthDayYear,
dateMonthDay,
daysFromDate,
diffDays,
add,
getMonths,
getMonthName,
isCurrentMonth,
gteFromFilter,
getDuration,
getDurationInSeconds,
getDateStartOfDay,
getDateEndOfDay,
};