Skip to content

Commit 0bdaf96

Browse files
committed
fix(blog-list): format string dates without timezone shift
1 parent 6b986ac commit 0bdaf96

1 file changed

Lines changed: 47 additions & 6 deletions

File tree

src/blog-list/index.tsx

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,59 @@ const getClassName = (...classNames: Array<string | false | undefined>) => {
7171
return classNames.filter(Boolean).join(' ');
7272
};
7373

74+
// 2025-6-26 16:00:00
75+
const ISO_DATE_PREFIX_RE = /^(\d{4})-(\d{2})-(\d{2})(?:$|[T\s])/;
76+
77+
const getDatePartsFromString = (value: string) => {
78+
const match = ISO_DATE_PREFIX_RE.exec(value.trim());
79+
80+
if (!match) {
81+
return undefined;
82+
}
83+
84+
const [, year, month, day] = match;
85+
86+
return {
87+
year: Number(year),
88+
month: Number(month),
89+
day: Number(day),
90+
};
91+
};
92+
7493
const normalizeDate = (value?: BlogDateValue) => {
7594
if (value === undefined) {
7695
return undefined;
7796
}
7897

79-
const date = value instanceof Date ? value : new Date(value);
98+
const date =
99+
value instanceof Date
100+
? value
101+
: typeof value === 'string'
102+
? new Date(value)
103+
: new Date(value);
80104

81105
return Number.isNaN(date.getTime()) ? undefined : date;
82106
};
83107

108+
const formatBlogDate = (
109+
value: BlogDateValue | undefined,
110+
formatter: Intl.DateTimeFormat,
111+
) => {
112+
if (typeof value === 'string') {
113+
const dateParts = getDatePartsFromString(value);
114+
115+
if (dateParts) {
116+
return formatter.format(
117+
new Date(dateParts.year, dateParts.month - 1, dateParts.day),
118+
);
119+
}
120+
}
121+
122+
const date = normalizeDate(value);
123+
124+
return date ? formatter.format(date) : undefined;
125+
};
126+
84127
const getPostKey = (post: BlogListItem, index: number) => {
85128
if (post.id !== undefined) {
86129
return post.id;
@@ -171,7 +214,7 @@ function BlogCard({
171214
interactive,
172215
renderInlineMarkdown,
173216
}: BlogCardProps) {
174-
const normalizedDate = normalizeDate(post.date);
217+
const formattedDate = formatBlogDate(post.date, dateFormatter);
175218
const isInteractive = interactive && Boolean(post.href);
176219
const hasTitle = hasContent(post.title);
177220
const hasDescription = hasContent(post.description);
@@ -195,10 +238,8 @@ function BlogCard({
195238

196239
const cardContent = (
197240
<>
198-
{normalizedDate ? (
199-
<span className={styles.date}>
200-
{dateFormatter.format(normalizedDate)}
201-
</span>
241+
{formattedDate ? (
242+
<span className={styles.date}>{formattedDate}</span>
202243
) : null}
203244
{hasTitle ? <div className={titleClassName}>{post.title}</div> : null}
204245
{hasDescription ? (

0 commit comments

Comments
 (0)