UNPKG

@cometchat/chat-uikit-react

Version:

Ready-to-use Chat UI Components for React

270 lines (267 loc) 9.52 kB
import './index.css'; // src/resources/CometChatLocalize/dateFormat.utils.ts var DEFAULT_FORMAT_CONFIG = { today: "Today", yesterday: "Yesterday", lastWeek: "dddd", otherDays: "DD MMM, YYYY" }; function formatDateWithConfig(timestamp, config, options) { const mergedConfig = { ...DEFAULT_FORMAT_CONFIG, ...config }; const date = new Date(timestamp * 1e3); const now = /* @__PURE__ */ new Date(); const timezone = options?.timezone; const locale = options?.locale; const dateInTz = timezone ? getDatePartsInTimezone(date, timezone) : getLocalDateParts(date); const nowInTz = timezone ? getDatePartsInTimezone(now, timezone) : getLocalDateParts(now); const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1e3); const diffInMinutes = Math.floor(diffInSeconds / 60); const diffInHours = Math.floor(diffInMinutes / 60); if (mergedConfig.relativeTime && Object.keys(mergedConfig.relativeTime).length > 0) { if (diffInSeconds >= 0 && diffInSeconds < 60) { if (mergedConfig.relativeTime.minute) { return mergedConfig.relativeTime.minute.includes("%d") ? mergedConfig.relativeTime.minute.replace("%d", "1") : mergedConfig.relativeTime.minute; } if (mergedConfig.today) { return formatDateFromPattern(date, mergedConfig.today, { timezone, locale }); } } if (diffInMinutes >= 1 && diffInMinutes < 60) { if (mergedConfig.relativeTime.minutes) { return mergedConfig.relativeTime.minutes.includes("%d") ? mergedConfig.relativeTime.minutes.replace("%d", String(diffInMinutes)) : mergedConfig.relativeTime.minutes; } if (mergedConfig.today) { return formatDateFromPattern(date, mergedConfig.today, { timezone, locale }); } } if (diffInHours >= 1 && diffInHours < 24) { if (diffInHours === 1 && mergedConfig.relativeTime.hour) { return mergedConfig.relativeTime.hour.replace("%d", "1"); } if (mergedConfig.relativeTime.hours) { return mergedConfig.relativeTime.hours.replace("%d", String(diffInHours)); } } } if (isSameDay(dateInTz, nowInTz) && mergedConfig.today) { return formatDateFromPattern(date, mergedConfig.today, { timezone, locale }); } if (isYesterday(dateInTz, nowInTz) && mergedConfig.yesterday) { return formatDateFromPattern(date, mergedConfig.yesterday, { timezone, locale }); } const diffInDays = Math.floor((now.getTime() - date.getTime()) / (1e3 * 60 * 60 * 24)); if (diffInDays <= 7 && mergedConfig.lastWeek) { return formatDateFromPattern(date, mergedConfig.lastWeek, { timezone, locale }); } return formatDateFromPattern(date, mergedConfig.otherDays ?? "DD/MM/YYYY", { timezone, locale }); } function getDatePartsInTimezone(date, timezone) { try { const formatter = new Intl.DateTimeFormat("en-US", { timeZone: timezone, year: "numeric", month: "numeric", day: "numeric" }); const parts = formatter.formatToParts(date); let year = 0, month = 0, day = 0; for (const part of parts) { if (part.type === "year") year = parseInt(part.value, 10); if (part.type === "month") month = parseInt(part.value, 10); if (part.type === "day") day = parseInt(part.value, 10); } return { year, month, day }; } catch { return getLocalDateParts(date); } } function getLocalDateParts(date) { return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate() }; } function isSameDay(a, b) { return a.year === b.year && a.month === b.month && a.day === b.day; } function isYesterday(date, reference) { const refDate = new Date(reference.year, reference.month - 1, reference.day); refDate.setDate(refDate.getDate() - 1); const yesterday = { year: refDate.getFullYear(), month: refDate.getMonth() + 1, day: refDate.getDate() }; return isSameDay(date, yesterday); } var SHORT_MONTHS = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; var LONG_MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var LONG_WEEKDAYS = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; var SHORT_WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; var MIN_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; function formatDateFromPattern(date, format, options) { const hasUpperA = /\bA\b/.test(format); const hasLowerA = /\ba\b/.test(format); const intlOptions = { day: format.includes("D") ? "2-digit" : void 0, month: format.includes("MMMM") || format.includes("MMM") || format.includes("MM") || format.includes("M") ? "2-digit" : void 0, year: format.includes("YYYY") ? "numeric" : format.includes("YY") ? "2-digit" : void 0, hour: format.includes("hh") ? "2-digit" : format.includes("h") ? "numeric" : void 0, minute: format.includes("mm") ? "2-digit" : format.includes("m") ? "numeric" : void 0, hour12: hasUpperA || hasLowerA, weekday: format.includes("dddd") ? "long" : format.includes("ddd") || format.includes("dd") ? "short" : void 0 }; if (options?.timezone) { intlOptions.timeZone = options.timezone; } const hasTokens = Object.values(intlOptions).some((v) => v !== void 0 && v !== false); if (!hasTokens) { return format; } const locale = options?.locale || "en-US"; try { const formatter = new Intl.DateTimeFormat(locale, intlOptions); const parts = formatter.formatToParts(date); const dayIndex = options?.timezone ? getDayOfWeekInTimezone(date, options.timezone) : date.getDay(); const r = { DD: "", D: "", MM: "", M: "", MMM: "", MMMM: "", YYYY: "", YY: "", hh: "", h: "", mm: "", m: "", A: "", a: "", dddd: "", ddd: "", dd: "" }; for (const part of parts) { switch (part.type) { case "day": r.DD = part.value; r.D = parseInt(part.value, 10).toString(); break; case "month": { const monthIndex = parseInt(part.value, 10) - 1; r.MM = part.value; r.M = parseInt(part.value, 10).toString(); r.MMM = getLocalizedMonthName(date, "short", locale, options?.timezone) ?? SHORT_MONTHS[monthIndex] ?? part.value; r.MMMM = getLocalizedMonthName(date, "long", locale, options?.timezone) ?? LONG_MONTHS[monthIndex] ?? part.value; break; } case "year": r.YYYY = part.value; r.YY = part.value.slice(-2); break; case "hour": r.hh = part.value; r.h = parseInt(part.value, 10).toString(); break; case "minute": r.mm = part.value; r.m = parseInt(part.value, 10).toString(); break; case "dayPeriod": r.A = part.value; r.a = part.value.toLowerCase(); break; case "weekday": r.dddd = getLocalizedWeekdayName(date, "long", locale, options?.timezone) ?? LONG_WEEKDAYS[dayIndex] ?? part.value; r.ddd = getLocalizedWeekdayName(date, "short", locale, options?.timezone) ?? SHORT_WEEKDAYS[dayIndex] ?? part.value; r.dd = getLocalizedWeekdayName(date, "narrow", locale, options?.timezone) ?? MIN_WEEKDAYS[dayIndex] ?? part.value; break; } } return format.replace(/\[(.*?)\]/g, "$1").replace(/\bDD\b/g, r.DD).replace(/\bD\b/g, r.D).replace(/\bMMMM\b/g, r.MMMM).replace(/\bMMM\b/g, r.MMM).replace(/\bMM\b/g, r.MM).replace(/\bM\b/g, r.M).replace(/\bYYYY\b/g, r.YYYY).replace(/\bYY\b/g, r.YY).replace(/\bhh\b/g, r.hh).replace(/\bh\b/g, r.h).replace(/\bmm\b/g, r.mm).replace(/\bm\b/g, r.m).replace(/\bdddd\b/g, r.dddd).replace(/\bddd\b/g, r.ddd).replace(/\bdd\b/g, r.dd).replace(/\sA\s/g, ` ${r.A || "A"} `).replace(/^A\s/g, `${r.A || "A"} `).replace(/\sA$/, ` ${r.A || "A"}`).replace(/^A$/, r.A || "A").replace(/\sa\s/g, ` ${r.a || "a"} `).replace(/^a\s/g, `${r.a || "a"} `).replace(/\sa$/, ` ${r.a || "a"}`).replace(/^a$/, r.a || "a"); } catch { return date.toLocaleDateString(); } } function getDayOfWeekInTimezone(date, timezone) { try { const formatter = new Intl.DateTimeFormat("en-US", { timeZone: timezone, weekday: "short" }); const weekday = formatter.format(date); const index = SHORT_WEEKDAYS.indexOf(weekday); return index >= 0 ? index : date.getDay(); } catch { return date.getDay(); } } function getLocalizedWeekdayName(date, style, locale, timezone) { try { const opts = { weekday: style }; if (timezone) opts.timeZone = timezone; return new Intl.DateTimeFormat(locale, opts).format(date); } catch { return void 0; } } function getLocalizedMonthName(date, style, locale, timezone) { try { const opts = { month: style }; if (timezone) opts.timeZone = timezone; return new Intl.DateTimeFormat(locale, opts).format(date); } catch { return void 0; } } function formatFullDateLabel(date, options) { try { const intlOptions = { dateStyle: "long", timeStyle: "short" }; if (options?.timezone) { intlOptions.timeZone = options.timezone; } return new Intl.DateTimeFormat(options?.locale || "en-US", intlOptions).format(date); } catch { return date.toLocaleString(); } } export { formatDateWithConfig, formatFullDateLabel };