Skip to content

Commit 4b89a8c

Browse files
committed
feat: implement toDisplayDate utility function and integrate it into BlogSubHeader and Posts components
1 parent cdbc77e commit 4b89a8c

4 files changed

Lines changed: 53 additions & 17 deletions

File tree

src/components/app/blog/BlogSubHeader.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { toDisplayDate } from "./utils";
2+
13
type Props = {
24
hidden?: boolean;
35
date?: string;
@@ -12,7 +14,7 @@ const BlogSubHeader = ({ hidden, date, title, excerpt }: Props) => {
1214
{date && (
1315
<div className="mb-8 flex items-center gap-4">
1416
<div className="flex items-center gap-2 whitespace-nowrap font-mono text-sm text-primary bg-primary/10 px-2 py-1 rounded tracking-widest">
15-
<span>{date} //</span>
17+
<span className={"uppercase"}>{toDisplayDate(date)} //</span>
1618
<span className="text-primary">ENTRY_RECORD</span>
1719
{hidden && process.env.NODE_ENV === "development" && (
1820
<span className="rounded bg-tertiary/18 px-2 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-tertiary">

src/components/app/blog/Posts.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,15 @@ import classNames from "classnames";
22

33
import { type Frontmatter } from "types/frontmatter";
44

5+
import { toDisplayDate } from "./utils";
6+
57
interface Props {
68
posts?: Frontmatter[];
79
}
810

911
const postCardClassName =
1012
"group flex h-full flex-col rounded-2xl border border-outline-variant bg-surface-container-low px-7 py-8 transition-all duration-150 ease-out hover:border-primary/70 hover:bg-surface-container focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/70 focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-[0.995]";
1113

12-
const toDisplayDate = (rawDate?: string) => {
13-
if (!rawDate) {
14-
return "UNKNOWN";
15-
}
16-
17-
const parsedDate = new Date(rawDate);
18-
if (Number.isNaN(parsedDate.getTime())) {
19-
return rawDate;
20-
}
21-
22-
const year = parsedDate.getFullYear();
23-
const month = String(parsedDate.getMonth() + 1).padStart(2, "0");
24-
const day = String(parsedDate.getDate()).padStart(2, "0");
25-
return `${year}.${month}.${day}`;
26-
};
27-
2814
const toNodeId = (index: number) =>
2915
`SYSLOG_${String(index + 1).padStart(2, "0")}`;
3016

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { describe, expect, test } from "vitest";
2+
3+
import { toDisplayDate } from "./utils";
4+
5+
describe("toDisplayDate", () => {
6+
test("returns UNKNOWN when no date is provided", () => {
7+
expect(toDisplayDate()).toBe("UNKNOWN");
8+
expect(toDisplayDate(undefined)).toBe("UNKNOWN");
9+
});
10+
11+
test("returns the raw string when it cannot be parsed as a date", () => {
12+
expect(toDisplayDate("not-a-date")).toBe("not-a-date");
13+
});
14+
15+
test("formats a valid ISO date string as a US long-form date", () => {
16+
expect(toDisplayDate("2026-03-23")).toBe("March 23, 2026");
17+
});
18+
19+
test("formats January correctly", () => {
20+
expect(toDisplayDate("2024-01-01")).toBe("January 1, 2024");
21+
});
22+
23+
test("formats December correctly", () => {
24+
expect(toDisplayDate("2023-12-31")).toBe("December 31, 2023");
25+
});
26+
27+
test("does not shift the day due to timezone offset", () => {
28+
// Dates stored as YYYY-MM-DD should not drift to the previous day
29+
expect(toDisplayDate("2025-07-04")).toBe("July 4, 2025");
30+
});
31+
});

src/components/app/blog/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export const toDisplayDate = (rawDate?: string) => {
2+
if (!rawDate) {
3+
return "UNKNOWN";
4+
}
5+
6+
const parsedDate = new Date(rawDate);
7+
if (Number.isNaN(parsedDate.getTime())) {
8+
return rawDate;
9+
}
10+
11+
return parsedDate.toLocaleDateString("en-US", {
12+
year: "numeric",
13+
month: "long",
14+
day: "numeric",
15+
timeZone: "UTC",
16+
});
17+
};

0 commit comments

Comments
 (0)