summaryrefslogtreecommitdiff
path: root/frontend/lib/format.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/lib/format.ts')
-rw-r--r--frontend/lib/format.ts35
1 files changed, 35 insertions, 0 deletions
diff --git a/frontend/lib/format.ts b/frontend/lib/format.ts
index 34bffd8..6a1fcc2 100644
--- a/frontend/lib/format.ts
+++ b/frontend/lib/format.ts
@@ -29,3 +29,38 @@ export function deltaClass(value?: number | null): string {
if (value === null || value === undefined) return "neutral";
return value >= 0 ? "positive" : "negative";
}
+
+export function formatNewsTimestamp(iso: string): { display: string; iso: string } {
+ const date = new Date(iso);
+ const now = new Date();
+ const tz: Intl.DateTimeFormatOptions = { timeZone: "America/Los_Angeles" };
+ const diffMs = now.getTime() - date.getTime();
+ const diffMins = Math.floor(diffMs / 60_000);
+ const diffHours = Math.floor(diffMs / 3_600_000);
+
+ if (diffMins < 1) {
+ return { display: "Just now", iso };
+ }
+ if (diffMins < 60) {
+ return { display: `${diffMins}m ago`, iso };
+ }
+ if (diffHours < 24) {
+ return { display: `${diffHours}h ago`, iso };
+ }
+
+ const inTz = (options: Intl.DateTimeFormatOptions) =>
+ date.toLocaleString("en-US", { ...options, ...tz });
+
+ if (diffHours < 48) {
+ const time = inTz({ hour: "numeric", minute: "2-digit" });
+ return { display: `Yesterday ${time}`, iso };
+ }
+
+ const yearNow = Number(now.toLocaleString("en-US", { year: "numeric", ...tz }));
+ const yearDate = Number(inTz({ year: "numeric" }));
+
+ if (yearDate === yearNow) {
+ return { display: inTz({ month: "short", day: "numeric" }), iso };
+ }
+ return { display: inTz({ month: "short", day: "numeric", year: "numeric" }), iso };
+}