feat: add date formatting component and configuration options

- Add DateFormat and PostTime components, supporting multiple date display formats
- Add dateFormat option in theme configuration, allowing customization of date display styles
- Refactor time display logic in article list and article detail pages
- Update configuration type definitions to support new date format options
This commit is contained in:
radishzzz 2025-03-11 15:33:39 +00:00
parent 4b21e6ee39
commit 8ac9b865f5
7 changed files with 184 additions and 30 deletions

View file

@ -0,0 +1,78 @@
---
import { themeConfig } from '@/config'
import { isPostPage } from '@/utils/path'
interface Props {
date: Date
updatedDate?: Date
minutes?: number
}
const { date, updatedDate, minutes } = Astro.props
const format = themeConfig.global.dateFormat
const currentPath = Astro.url.pathname
const isPost = isPostPage(currentPath)
const updatedTimeMarginClass = isPost ? 'ml-1.75' : 'ml-1.5'
const readingTimeMarginClass = isPost ? 'ml-1.75' : 'ml-1.5'
function formatDate(date: Date, format: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MONTH DAY YYYY' | 'DAY MONTH YYYY') {
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: format === 'MONTH DAY YYYY' || format === 'DAY MONTH YYYY' ? 'short' : '2-digit',
day: format === 'MONTH DAY YYYY' || format === 'DAY MONTH YYYY' ? 'numeric' : '2-digit',
}
switch (format) {
// ISO format: 2024-03-04
case 'YYYY-MM-DD':
return date.toISOString().split('T')[0]
// US date format: 03-04-2024
case 'MM-DD-YYYY':
return date.toLocaleDateString('en-US', options).replace(/\//g, '-')
// European date format: 04-03-2024
case 'DD-MM-YYYY':
return date.toLocaleDateString('en-GB', options).replace(/\//g, '-')
// US month text format: Mar 4 2024
case 'MONTH DAY YYYY':
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).replace(',', '')
// British month text format: 4 Mar 2024
case 'DAY MONTH YYYY':
return date.toLocaleDateString('en-GB', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).replace(',', '')
// Default to ISO format
default:
return date.toISOString().split('T')[0]
}
}
---
<!-- published time -->
<time datetime={date.toISOString().split('T')[0]}>
{formatDate(date, format)}
</time>
<!-- updated time -->
{updatedDate && (
<time datetime={updatedDate.toISOString().split('T')[0]} class={updatedTimeMarginClass}>
updated {formatDate(updatedDate, format)}
</time>
)}
<!-- reading time -->
{minutes !== undefined && (
<span class={readingTimeMarginClass}>
{minutes} min
</span>
)}