@cch137/format-utils
Version:
A collection of utility modules for formatting and processing data
147 lines (146 loc) • 5.04 kB
JavaScript
const tokenConverterMap = (() => {
const fullMonthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const abbvMonthNames = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
const fullDayNames = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const abbvDayNames = [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
];
const padStart = (val, len = 2) => String(val).padStart(len, "0");
const getY = (date, isUTC) => isUTC ? date.getUTCFullYear() : date.getFullYear();
const getH24 = (date, isUTC) => isUTC ? date.getUTCHours() : date.getHours();
const getH12 = (date, isUTC) => (isUTC ? date.getUTCHours() : date.getHours()) % 12;
const getMin = (date, isUTC) => isUTC ? date.getUTCMinutes() : date.getMinutes();
const getSec = (date, isUTC) => isUTC ? date.getUTCSeconds() : date.getSeconds();
const getF = (date, isUTC) => isUTC ? date.getUTCMilliseconds() : date.getMilliseconds();
const getDay = (date, isUTC) => isUTC ? date.getUTCDay() : date.getDay();
const getDate = (date, isUTC) => isUTC ? date.getUTCDate() : date.getDate();
const getMonth = (date, isUTC) => (isUTC ? date.getUTCMonth() : date.getMonth()) + 1;
const returnString = (f) => (date, isUTC) => String(f(date, isUTC));
return [
["yyyy", (d, u) => padStart(getY(d, u), 4)],
["yy", (d, u) => padStart(getY(d, u))],
["y", returnString(getY)],
["HH", (d, u) => padStart(getH24(d, u))],
["H", returnString(getH24)],
["hh", (d, u) => padStart(getH12(d, u))],
["h", returnString(getH12)],
["mm", (d, u) => padStart(getMin(d, u))],
["m", returnString(getMin)],
["ss", (d, u) => padStart(getSec(d, u))],
["s", returnString(getSec)],
["fff", (d, u) => padStart(getF(d, u), 3)],
["ff", (d, u) => padStart(Math.round(getF(d, u) / 10))],
["f", (d, u) => String(Math.round(getF(d, u) / 100))],
["tt", (d, u) => (getH24(d, u) < 12 ? "am" : "pm")],
["t", (d, u) => (getH24(d, u) < 12 ? "a" : "p")],
["TT", (d, u) => (getH24(d, u) < 12 ? "AM" : "PM")],
["T", (d, u) => (getH24(d, u) < 12 ? "A" : "P")],
["dddd", (d, u) => fullDayNames[getDay(d, u)]],
["DDD", (d, u) => abbvDayNames[getDay(d, u)].toUpperCase()],
["ddd", (d, u) => abbvDayNames[getDay(d, u)]],
["dd", (d, u) => padStart(getDate(d, u))],
["d", returnString(getDate)],
["MMMM", (d, u) => fullMonthNames[getMonth(d, u) - 1]],
["MMM", (d, u) => abbvMonthNames[getMonth(d, u) - 1].toUpperCase()],
["mmm", (d, u) => abbvMonthNames[getMonth(d, u) - 1]],
["MM", (d, u) => padStart(getMonth(d, u))],
["M", returnString(getMonth)],
];
})();
export function formatDate(date, format = "yyyy-MM-dd HH:mm:ss", isUTC = false) {
const parts = [];
while (format.length > 0) {
const matched = tokenConverterMap.find(([token]) => format.startsWith(token));
if (!matched) {
parts.push(format[0]);
format = format.substring(1);
continue;
}
const [token, converter] = matched;
parts.push(converter(date, isUTC));
format = format.substring(token.length);
}
return parts.join("");
}
export default formatDate;
export function formatRelativeDate(date, locale = "en", dateFormatOptions = {
year: "numeric",
month: "2-digit",
day: "2-digit",
}) {
if (!(date instanceof Date) || isNaN(date.getTime())) {
throw new Error("Invalid date");
}
const now = new Date();
const diffMs = now.getTime() - date.getTime();
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffDays > 15) {
const dtf = new Intl.DateTimeFormat(locale, dateFormatOptions);
return dtf.format(date);
}
const diffSeconds = Math.floor(diffMs / 1000);
const diffMinutes = Math.floor(diffSeconds / 60);
const diffHours = Math.floor(diffMinutes / 60);
const rtf = new Intl.RelativeTimeFormat(locale, {
numeric: "auto",
style: "long",
});
if (diffDays >= 2) {
return rtf.format(-diffDays, "day");
}
else if (diffDays === 1) {
return rtf.format(-1, "day");
}
else if (diffHours >= 1) {
return rtf.format(-diffHours, "hour");
}
else if (diffMinutes >= 1) {
return rtf.format(-diffMinutes, "minute");
}
else if (diffSeconds <= 1) {
return "just now";
}
else {
return rtf.format(-diffSeconds, "second");
}
}