This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / format.ts
2.5 kB 64 lines
1const DIVISIONS: { amount: number; unit: Intl.RelativeTimeFormatUnit }[] = [ 2 { amount: 60, unit: "seconds" }, 3 { amount: 60, unit: "minutes" }, 4 { amount: 24, unit: "hours" }, 5 { amount: 7, unit: "days" }, 6 { amount: 4.34524, unit: "weeks" }, 7 { amount: 12, unit: "months" }, 8 { amount: Number.POSITIVE_INFINITY, unit: "years" } 9]; 10 11const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" }); 12const dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" }); 13// the appview's longTimeFmt ("Jan 2, 2006, 3:04 PM MST") 14const dtfFull = new Intl.DateTimeFormat("en", { 15 year: "numeric", 16 month: "short", 17 day: "numeric", 18 hour: "numeric", 19 minute: "2-digit", 20 timeZoneName: "short" 21}); 22 23// "3 days ago", "in 2 hours", etc. 24export const relativeTime = (input: string | Date, now: Date = new Date()): string => { 25 const date = typeof input === "string" ? new Date(input) : input; 26 if (Number.isNaN(date.getTime())) return ""; 27 let duration = (date.getTime() - now.getTime()) / 1000; 28 for (const division of DIVISIONS) { 29 if (Math.abs(duration) < division.amount) 30 return rtf.format(Math.round(duration), division.unit); 31 duration /= division.amount; 32 } 33 return rtf.format(Math.round(duration), "years"); 34}; 35export const compactRelativeTime = (input: string | Date, now: Date = new Date()): string => { 36 const date = typeof input === "string" ? new Date(input) : input; 37 if (Number.isNaN(date.getTime())) return ""; 38 let duration = Math.abs((now.getTime() - date.getTime()) / 1000); 39 const suffix = date.getTime() > now.getTime() ? "from now" : "ago"; 40 41 if (duration < 60) return `${Math.floor(duration)}s ${suffix}`; 42 duration /= 60; 43 if (duration < 60) return `${Math.floor(duration)}m ${suffix}`; 44 duration /= 60; 45 if (duration < 24) return `${Math.floor(duration)}h ${suffix}`; 46 duration /= 24; 47 if (duration < 7) return `${Math.floor(duration)}d ${suffix}`; 48 duration /= 7; 49 if (duration < 4.34524) return `${Math.floor(duration)}w ${suffix}`; 50 duration /= 4.34524; 51 if (duration < 12) return `${Math.floor(duration)}mo ${suffix}`; 52 duration /= 12; 53 return `${Math.floor(duration)}y ${suffix}`; 54}; 55 56export const formatDate = (input: string | Date): string => { 57 const date = typeof input === "string" ? new Date(input) : input; 58 return Number.isNaN(date.getTime()) ? "" : dtf.format(date); 59}; 60 61export const formatDateTime = (input: string | Date): string => { 62 const date = typeof input === "string" ? new Date(input) : input; 63 return Number.isNaN(date.getTime()) ? "" : dtfFull.format(date); 64};